{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0174dt6swdca",
   "metadata": {},
   "source": [
    "# 数据加载与检查\n",
    " \n",
    " 本单元用于加载和检查MBPP数据集的两个版本：\n",
    " - mbpp.jsonl: 原始JSONL格式数据集（每行一个JSON对象）\n",
    " - sanitized-mbpp.json: 清洗后的标准JSON格式数据集\n",
    " \n",
    "这些数据集包含编程问题描述和对应的代码解决方案，将用于embedding模型的训练。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d4a216fe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "检查文件: ./mbpp.jsonl -> 存在\n",
      "检查文件: ./sanitized-mbpp.json -> 存在\n",
      "已加载 mbpp.jsonl，样本数=974\n",
      "已加载 sanitized-mbpp.json，样本数=427\n",
      "\n",
      "--- mbpp.jsonl 第一条示例（部分） ---\n",
      "{'challenge_test_list': [],\n",
      " 'code': 'R = 3\\r\\n'\n",
      "         'C = 3\\r\\n'\n",
      "         'def min_cost(cost, m, n): \\r\\n'\n",
      "         '\\ttc = [[0 for x in range(C)] for x in range(R)] \\r\\n'\n",
      "         '\\ttc[0][0] = cost[0][0] \\r\\n'\n",
      "         '\\tfor i in range(1, m+1): \\r\\n'\n",
      "         '\\t\\ttc[i][0] = tc[i-1][0] + cost[i][0] \\r\\n'\n",
      "         '\\tfor j in range(1, n+1): \\r\\n'\n",
      "         '\\t\\ttc[0][j] = tc[0][j-1] + cost[0][j] \\r\\n'\n",
      "         '\\tfor i in range(1, m+1): \\r\\n'\n",
      "         '\\t\\tfor j in range(1, n+1): \\r\\n'\n",
      "         '\\t\\t\\ttc[i][j] = min(tc[i-1][j-1], tc[i-1][j], tc[i][j-1]) + '\n",
      "         'cost[i][j] \\r\\n'\n",
      "         '\\treturn tc[m][n]',\n",
      " 'task_id': 1,\n",
      " 'test_list': ['assert min_cost([[1, 2, 3], [4, 8, 2], [1, 5, 3]], 2, 2) == 8',\n",
      "               'assert min_cost([[2, 3, 4], [5, 9, 3], [2, 6, 4]], 2, 2) == 12',\n",
      "               'assert min_cost([[3, 4, 5], [6, 10, 4], [3, 7, 5]], 2, 2) == '\n",
      "               '16'],\n",
      " 'test_setup_code': '',\n",
      " 'text': 'Write a function to find the minimum cost path to reach (m, n) from '\n",
      "         '(0, 0) for the given cost matrix cost[][] and a position (m, n) in '\n",
      "         'cost[][].'}\n",
      "\n",
      "--- sanitized-mbpp.json 第一条示例（部分） ---\n",
      "{'code': 'def similar_elements(test_tup1, test_tup2):\\n'\n",
      "         '  res = tuple(set(test_tup1) & set(test_tup2))\\n'\n",
      "         '  return (res) ',\n",
      " 'prompt': 'Write a function to find the shared elements from the given two '\n",
      "           'lists.',\n",
      " 'source_file': 'Benchmark Questions Verification V2.ipynb',\n",
      " 'task_id': 2,\n",
      " 'test_imports': [],\n",
      " 'test_list': ['assert set(similar_elements((3, 4, 5, 6),(5, 7, 4, 10))) == '\n",
      "               'set((4, 5))',\n",
      "               'assert set(similar_elements((1, 2, 3, 4),(5, 4, 3, 7))) == '\n",
      "               'set((3, 4))',\n",
      "               'assert set(similar_elements((11, 12, 14, 13),(17, 15, 14, '\n",
      "               '13))) == set((13, 14))']}\n",
      "\n",
      "可用变量: loaded_mbpp, loaded_sanitized\n"
     ]
    }
   ],
   "source": [
    "# 从本地文件加载 MBPP 数据（不使用 datasets 库）\n",
    "import json\n",
    "import os\n",
    "from pprint import pprint\n",
    "\n",
    "jsonl_path = \"./mbpp.jsonl\"\n",
    "json_path = \"./sanitized-mbpp.json\"\n",
    "\n",
    "for p in (jsonl_path, json_path):\n",
    "    print(f\"检查文件: {p} -> {'存在' if os.path.exists(p) else '未找到'}\")\n",
    "\n",
    "# 加载 jsonl（每行一个 JSON）\n",
    "def load_jsonl(path):\n",
    "    items = []\n",
    "    with open(path, 'r', encoding='utf-8') as f:\n",
    "        for i, line in enumerate(f):\n",
    "            line = line.strip()\n",
    "            if not line:\n",
    "                continue\n",
    "            try:\n",
    "                items.append(json.loads(line))\n",
    "            except Exception as e:\n",
    "                print(f\"解析 {path} 第 {i} 行失败：\", type(e).__name__, e)\n",
    "    return items\n",
    "\n",
    "# 加载普通 json 文件\n",
    "def load_json(path):\n",
    "    with open(path, 'r', encoding='utf-8') as f:\n",
    "        return json.load(f)\n",
    "\n",
    "mbpp = []\n",
    "sanitized = []\n",
    "\n",
    "if os.path.exists(jsonl_path):\n",
    "    mbpp = load_jsonl(jsonl_path)\n",
    "    print(f\"已加载 mbpp.jsonl，样本数={len(mbpp)}\")\n",
    "else:\n",
    "    print(\"未找到 mbpp.jsonl，mbpp 列表为空\")\n",
    "\n",
    "if os.path.exists(json_path):\n",
    "    try:\n",
    "        sanitized = load_json(json_path)\n",
    "        print(f\"已加载 sanitized-mbpp.json，样本数={len(sanitized)}\")\n",
    "    except Exception as e:\n",
    "        print(\"加载 sanitized-mbpp.json 失败：\", type(e).__name__, e)\n",
    "else:\n",
    "    print(\"未找到 sanitized-mbpp.json，sanitized 列表为空\")\n",
    "\n",
    "# 打印第一条示例（如果存在）\n",
    "if mbpp:\n",
    "    print('\\n--- mbpp.jsonl 第一条示例（部分） ---')\n",
    "    pprint(mbpp[0])\n",
    "if sanitized:\n",
    "    print('\\n--- sanitized-mbpp.json 第一条示例（部分） ---')\n",
    "    pprint(sanitized[0])\n",
    "\n",
    "# 将加载的数据放到全局变量，方便 notebook 后续使用\n",
    "loaded_mbpp = mbpp\n",
    "loaded_sanitized = sanitized\n",
    "print('\\n可用变量: loaded_mbpp, loaded_sanitized')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a828ffcf",
   "metadata": {},
   "source": [
    "# 安装依赖\n",
    "pip install torch transformers sentence-transformers numpy matplotlib tqdm scipy scikit-learn\n",
    "\n",
    "## 数据集格式说明\n",
    "\n",
    "\n",
    "\n",
    "### 1) `mbpp.jsonl`（每行一个 JSON）\n",
    "- 说明：原始或完整版本，每行保存一条样本（JSONL）。常见字段：\n",
    "  - `source_file` (可选)：来源文件名\n",
    "  - `task_id`：任务编号（整数）\n",
    "  - `text` 或 `prompt`：题目描述（字符串）\n",
    "  - `code`：参考/标准答案代码（字符串）\n",
    "  - `test_imports`：测试所需的 import 语句列表（可选）\n",
    "  - `test_list`：测试断言列表（字符串数组），通常为可直接执行的 `assert ...` 文本\n",
    "  - `test_setup_code`：运行测试前需执行的准备代码（可选）\n",
    "  - `challenge_test_list`：扩展/挑战测试（可选）\n",
    "\n",
    "示例（单行 JSON，已格式化以便阅读，实际文件为 JSONL）：\n",
    "\n",
    "```json\n",
    "{\n",
    "  \"source_file\": \"Benchmark Questions Verification V2.ipynb\",\n",
    "  \"task_id\": 1,\n",
    "  \"text\": \"Write a function to find the minimum cost path to reach (m, n) from (0, 0) ...\",\n",
    "  \"code\": \"def min_cost(cost, m, n): ... return tc[m][n]\",\n",
    "  \"test_setup_code\": \"\",\n",
    "  \"test_list\": [\n",
    "    \"assert min_cost([[1,2,3],[4,8,2],[1,5,3]],2,2) == 8\",\n",
    "    \"assert min_cost([[2,3,4],[5,9,3],[2,6,4]],2,2) == 12\"\n",
    "  ],\n",
    "  \"challenge_test_list\": []\n",
    "}\n",
    "```\n",
    "\n",
    "---\n",
    "\n",
    "### 2) `sanitized-mbpp.json`（标准 JSON，整个文件为一个 JSON 数组）\n",
    "- 说明：经过清洗/规范化后的版本，通常以数组形式保存所有样本。字段与 `mbpp.jsonl` 类似，常见字段有：\n",
    "  - `task_id`：任务编号\n",
    "  - `prompt` 或 `text`：题目描述\n",
    "  - `code`：参考代码\n",
    "  - `test_imports`：测试所需 imports（数组）\n",
    "  - `test_list`：测试断言数组\n",
    "\n",
    "示例（数组中的一个对象）：\n",
    "\n",
    "```json\n",
    "{\n",
    "  \"task_id\": 2,\n",
    "  \"prompt\": \"Write a function to find the shared elements from the given two lists.\",\n",
    "  \"code\": \"def similar_elements(test_tup1, test_tup2):\\n  res = tuple(set(test_tup1) & set(test_tup2))\\n  return (res)\",\n",
    "  \"test_imports\": [],\n",
    "  \"test_list\": [\n",
    "    \"assert set(similar_elements((3,4,5,6),(5,7,4,10))) == set((4,5))\",\n",
    "    \"assert set(similar_elements((1,2,3,4),(5,4,3,7))) == set((3,4))\"\n",
    "  ]\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "48bbf4bb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "已加载 sanitized json，样本数=427\n",
      "总候选样本数: 427\n",
      "划分结果: total=427, train=341, val=86 (目标 8:2)\n",
      "写入完成: train -> ./mbpp_train.jsonl, val -> ./mbpp_val.jsonl\n"
     ]
    }
   ],
   "source": [
    "# 将 sanitized-mbpp.json 或 mbpp.jsonl -> mbpp_train.jsonl / mbpp_val.jsonl，按 8:2 划分\n",
    "import json, os, random\n",
    "\n",
    "mbpp_jsonl = \"./mbpp.jsonl\"\n",
    "sanitized_json = \"./sanitized-mbpp.json\"\n",
    "out_train = \"./mbpp_train.jsonl\"\n",
    "out_val = \"./mbpp_val.jsonl\"\n",
    "\n",
    "# 划分配置：8:2 (train:val)\n",
    "TRAIN_RATIO = 0.8\n",
    "VAL_RATIO = 0.2\n",
    "SEED = 42\n",
    "\n",
    "\n",
    "def load_jsonl(path):\n",
    "    items = []\n",
    "    with open(path, 'r', encoding='utf-8') as f:\n",
    "        for i, line in enumerate(f):\n",
    "            line = line.strip()\n",
    "            if not line:\n",
    "                continue\n",
    "            try:\n",
    "                items.append(json.loads(line))\n",
    "            except Exception as e:\n",
    "                print(f\"解析 {path} 第 {i} 行失败：\", type(e).__name__, e)\n",
    "    return items\n",
    "\n",
    "\n",
    "# 优先使用 sanitized_json（已清洗），否则尝试使用 mbpp_jsonl\n",
    "items = []\n",
    "if os.path.exists(sanitized_json):\n",
    "    try:\n",
    "        with open(sanitized_json, 'r', encoding='utf-8') as f:\n",
    "            items = json.load(f)\n",
    "        print(f\"已加载 sanitized json，样本数={len(items)}\")\n",
    "    except Exception as e:\n",
    "        print(\"加载 sanitized-mbpp.json 失败：\", type(e).__name__, e)\n",
    "\n",
    "if not items and os.path.exists(mbpp_jsonl):\n",
    "    print(f\"sanitized 未提供，尝试加载 jsonl: {mbpp_jsonl}\")\n",
    "    items = load_jsonl(mbpp_jsonl)\n",
    "    print(f\"已加载 mbpp.jsonl，样本数={len(items)}\")\n",
    "\n",
    "print(f\"总候选样本数: {len(items)}\")\n",
    "\n",
    "if len(items) == 0:\n",
    "    print('未找到可用样本，未写入 train/val 文件')\n",
    "else:\n",
    "    # 随机打乱并按比例划分（可复现）\n",
    "    random.seed(SEED)\n",
    "    random.shuffle(items)\n",
    "\n",
    "    n = len(items)\n",
    "    train_n = int(n * TRAIN_RATIO)\n",
    "    val_n = n - train_n\n",
    "\n",
    "    train_items = items[:train_n]\n",
    "    val_items = items[train_n:]\n",
    "\n",
    "    print(f\"划分结果: total={n}, train={len(train_items)}, val={len(val_items)} (目标 8:2)\")\n",
    "\n",
    "    # 写出文件（每行 JSON）\n",
    "    with open(out_train, 'w', encoding='utf-8') as f_train, open(out_val, 'w', encoding='utf-8') as f_val:\n",
    "        for item in train_items:\n",
    "            query = item.get('prompt') or item.get('text') or item.get('task') or \"\"\n",
    "            pos_doc = item.get('code') or item.get('solution') or \"\"\n",
    "            if query and pos_doc:\n",
    "                f_train.write(json.dumps({\"query\": query, \"pos_doc\": pos_doc, \"meta\": {\"task_id\": item.get(\"task_id\")}}, ensure_ascii=False) + \"\\n\")\n",
    "        for item in val_items:\n",
    "            query = item.get('prompt') or item.get('text') or item.get('task') or \"\"\n",
    "            pos_doc = item.get('code') or item.get('solution') or \"\"\n",
    "            if query and pos_doc:\n",
    "                f_val.write(json.dumps({\"query\": query, \"pos_doc\": pos_doc, \"meta\": {\"task_id\": item.get(\"task_id\")}}, ensure_ascii=False) + \"\\n\")\n",
    "\n",
    "    print(f\"写入完成: train -> {out_train}, val -> {out_val}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0mu545fflt6",
   "metadata": {},
   "source": [
    "# 数据预处理与划分\n",
    " \n",
    " 本单元将原始MBPP数据集转换为训练和验证集格式：\n",
    " - 从sanitized-mbpp.json或mbpp.jsonl加载数据\n",
    " - 按8:2比例随机划分为训练集和验证集\n",
    " - 将数据转换为query-pos_doc对格式，便于embedding模型训练\n",
    " - 保存为JSONL格式文件：mbpp_train.jsonl和mbpp_val.jsonl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88f10557",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 完整训练单元（放在 notebook 中运行）\n",
    "# 说明：本单元实现了基于 in-batch negatives 的嵌入微调流程，支持 fp16（AMP）和梯度累积。\n",
    "# 在运行之前，请确保已生成训练文件：./mbpp_train.jsonl\n",
    "import os\n",
    "# 设置tokenizers并行ism以避免DataLoader多进程警告\n",
    "os.environ[\"TOKENIZERS_PARALLELISM\"] = \"false\"\n",
    "\n",
    "import json\n",
    "from functools import partial\n",
    "from pprint import pprint\n",
    "\n",
    "import random\n",
    "import numpy as np\n",
    "\n",
    "import torch\n",
    "import torch.nn.functional as F\n",
    "from torch import nn\n",
    "from torch.utils.data import Dataset, DataLoader\n",
    "from transformers import AutoTokenizer, get_cosine_schedule_with_warmup\n",
    "from sentence_transformers import SentenceTransformer\n",
    "from tqdm.auto import tqdm\n",
    "\n",
    "\n",
    "# --------------------------- 数据集类 ---------------------------\n",
    "class JsonlDataset(Dataset):\n",
    "    def __init__(self, path):\n",
    "        assert os.path.exists(path), f\"训练文件不存在: {path}\"\n",
    "        self.samples = []\n",
    "        with open(path, 'r', encoding='utf-8') as f:\n",
    "            for i, line in enumerate(f):\n",
    "                line = line.strip()\n",
    "                if not line:\n",
    "                    continue\n",
    "                try:\n",
    "                    self.samples.append(json.loads(line))\n",
    "                except Exception as e:\n",
    "                    print(f\"解析第 {i} 行失败:\", e)\n",
    "        if len(self.samples) == 0:\n",
    "            raise ValueError(\"未在训练文件中读取到样本，请检查文件内容\")\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.samples)\n",
    "\n",
    "    def __getitem__(self, idx):\n",
    "        return self.samples[idx]\n",
    "\n",
    "# --------------------------- collate_fn ---------------------------\n",
    "def collate_fn(batch, tokenizer, query_max_len, passage_max_len):\n",
    "    queries = [item.get('query') or item.get('prompt') or item.get('text') or '' for item in batch]\n",
    "    pos_docs = [item.get('pos_doc') or item.get('code') or '' for item in batch]\n",
    "    # tokenizer 输出为 torch tensors\n",
    "    q = tokenizer(queries, padding=True, truncation=True, max_length=query_max_len, return_tensors='pt')\n",
    "    p = tokenizer(pos_docs, padding=True, truncation=True, max_length=passage_max_len, return_tensors='pt')\n",
    "    return {\n",
    "        'query_input_ids': q['input_ids'],\n",
    "        'query_attention_mask': q['attention_mask'],\n",
    "        'pos_doc_input_ids': p['input_ids'],\n",
    "        'pos_doc_attention_mask': p['attention_mask']\n",
    "    }\n",
    "\n",
    "# --------------------------- 模型封装 ---------------------------\n",
    "class EmbeddingModel(nn.Module):\n",
    "    def __init__(self, model_name_or_path, temperature=0.02):\n",
    "        super().__init__()\n",
    "        # 使用 SentenceTransformer 封装底层模型以获取 sentence_embedding\n",
    "        self.s2 = SentenceTransformer(model_name_or_path, trust_remote_code=True)\n",
    "        self.temperature = temperature\n",
    "\n",
    "    def forward(self, query_input_ids, query_attention_mask, pos_doc_input_ids, pos_doc_attention_mask):\n",
    "        # SentenceTransformer 接受 dict 输入并返回字典包含 'sentence_embedding'\n",
    "        q_emb = self.s2({'input_ids': query_input_ids, 'attention_mask': query_attention_mask})['sentence_embedding']\n",
    "        p_emb = self.s2({'input_ids': pos_doc_input_ids, 'attention_mask': pos_doc_attention_mask})['sentence_embedding']\n",
    "\n",
    "        q_emb = F.normalize(q_emb, p=2, dim=-1)\n",
    "        p_emb = F.normalize(p_emb, p=2, dim=-1)\n",
    "\n",
    "        sim = q_emb @ p_emb.t() / self.temperature\n",
    "        labels = torch.arange(sim.size(0), device=sim.device, dtype=torch.long)\n",
    "        loss = F.cross_entropy(sim, labels)\n",
    "        _, pred = sim.max(dim=1)\n",
    "        acc = (pred == labels).float().mean().item()\n",
    "        return { 'loss': loss, 'accuracy': acc }\n",
    "\n",
    "    def save(self, save_dir):\n",
    "        # 保存 SentenceTransformer 的底层模型和 tokenizer\n",
    "        os.makedirs(save_dir, exist_ok=True)\n",
    "        # SentenceTransformer 有 save 方法\n",
    "        self.s2.save(save_dir)\n",
    "\n",
    "# --------------------------- 训练流程 ---------------------------\n",
    "class Trainer:\n",
    "    def __init__(self, model, tokenizer, train_dataloader, optimizer, scheduler, device, cfg, val_dataloader=None):\n",
    "        self.model = model\n",
    "        self.tokenizer = tokenizer\n",
    "        self.dataloader = train_dataloader\n",
    "        self.optimizer = optimizer\n",
    "        self.scheduler = scheduler\n",
    "        self.device = device\n",
    "        self.cfg = cfg\n",
    "        self.val_dataloader = val_dataloader\n",
    "        self.scaler = torch.amp.GradScaler(enabled=cfg['fp16'])\n",
    "        # 训练历史记录\n",
    "        self.history = {\n",
    "            'step_losses': [],      # 每 step 的 loss\n",
    "            'step_accs': [],        # 每 step 的 acc\n",
    "            'epoch': [],            # epoch 索引\n",
    "            'epoch_loss': [],       # 每 epoch 平均 loss\n",
    "            'epoch_acc': [],        # 每 epoch 平均 acc\n",
    "            'eval': []              # 每 epoch 验证结果（dict）\n",
    "        }\n",
    "        # best metric tracking (使用 MRR 作为主要指标)\n",
    "        self.best_mrr = float('-inf')\n",
    "\n",
    "    def train_epoch(self, epoch):\n",
    "        self.model.train()\n",
    "        total_loss = 0.0\n",
    "        total_acc = 0.0\n",
    "        steps = 0\n",
    "\n",
    "        pbar = tqdm(self.dataloader, desc=f\"Epoch {epoch}\")\n",
    "        accumulation = self.cfg['accumulation_steps']\n",
    "\n",
    "        for step, batch in enumerate(pbar):\n",
    "            # move to device\n",
    "            batch = {k: v.to(self.device) for k, v in batch.items()}\n",
    "\n",
    "            with torch.cuda.amp.autocast(enabled=self.cfg['fp16']):\n",
    "                out = self.model(**batch)\n",
    "                loss = out['loss'] / accumulation\n",
    "\n",
    "            # 记录 step loss/acc（使用未除 accumulation 的原始 loss 用于监控）\n",
    "            self.history['step_losses'].append(out['loss'].item())\n",
    "            self.history['step_accs'].append(out['accuracy'])\n",
    "\n",
    "            self.scaler.scale(loss).backward()\n",
    "\n",
    "            if (step + 1) % accumulation == 0:\n",
    "                # clip grads\n",
    "                self.scaler.unscale_(self.optimizer)\n",
    "                torch.nn.utils.clip_grad_norm_(self.model.parameters(), 1.0)\n",
    "                self.scaler.step(self.optimizer)\n",
    "                self.scaler.update()\n",
    "                if self.scheduler is not None:\n",
    "                    self.scheduler.step()\n",
    "                self.optimizer.zero_grad()\n",
    "\n",
    "            total_loss += out['loss'].item()\n",
    "            total_acc += out['accuracy']\n",
    "            steps += 1\n",
    "            pbar.set_postfix({'loss': f\"{out['loss'].item():.4f}\", 'acc': f\"{out['accuracy']:.2%}\"})\n",
    "\n",
    "        avg_loss = total_loss / steps\n",
    "        avg_acc = total_acc / steps\n",
    "        # 记录 epoch 级别历史\n",
    "        self.history['epoch'].append(epoch)\n",
    "        self.history['epoch_loss'].append(avg_loss)\n",
    "        self.history['epoch_acc'].append(avg_acc)\n",
    "\n",
    "        print(f\"Epoch {epoch} finished. avg_loss={avg_loss:.4f}, avg_acc={avg_acc:.2%}\")\n",
    "\n",
    "    def evaluate(self, eval_max=None, batch_size=None):\n",
    "        # 在训练过程中使用 val_dataloader 的原始样本进行评估，返回 recall@1 与 mrr\n",
    "        if self.val_dataloader is None:\n",
    "            raise ValueError('没有可用的 val_dataloader，无法评估')\n",
    "        samples = getattr(self.val_dataloader.dataset, 'samples', None)\n",
    "        if samples is None or len(samples) == 0:\n",
    "            raise ValueError('val_dataloader.dataset 中没有样本')\n",
    "\n",
    "        eval_max = eval_max or self.cfg.get('eval_max', 1000)\n",
    "        batch_size = batch_size or self.cfg.get('eval_batch_size', 32)\n",
    "        # 构造 query / pos lists，限制样本数以提高速度\n",
    "        queries = [s.get('query') or s.get('prompt') or s.get('text') or '' for s in samples]\n",
    "        pos_docs = [s.get('pos_doc') or s.get('code') or '' for s in samples]\n",
    "        if len(queries) > eval_max:\n",
    "            idxs = random.sample(range(len(queries)), eval_max)\n",
    "            queries = [queries[i] for i in idxs]\n",
    "            pos_docs = [pos_docs[i] for i in idxs]\n",
    "\n",
    "        # 使用底层 SentenceTransformer 进行编码（支持 GPU）\n",
    "        device_str = str(self.device)\n",
    "        s = self.model.s2\n",
    "        print(f\"Evaluating on {len(queries)} samples, using device {device_str} ...\")\n",
    "        q_emb = s.encode(queries, batch_size=batch_size, convert_to_tensor=True, device=device_str, show_progress_bar=True)\n",
    "        p_emb = s.encode(pos_docs, batch_size=batch_size, convert_to_tensor=True, device=device_str, show_progress_bar=True)\n",
    "\n",
    "        q_emb = torch.nn.functional.normalize(q_emb, p=2, dim=-1)\n",
    "        p_emb = torch.nn.functional.normalize(p_emb, p=2, dim=-1)\n",
    "\n",
    "        sim = (q_emb @ p_emb.T).cpu().numpy()\n",
    "        n = sim.shape[0]\n",
    "        ranks = []\n",
    "        for i in range(n):\n",
    "            order = np.argsort(-sim[i])\n",
    "            rank = int(np.where(order == i)[0][0])\n",
    "            ranks.append(rank)\n",
    "        ranks = np.array(ranks)\n",
    "        recall_at_1 = float(np.mean(ranks == 0))\n",
    "        mrr = float(np.mean(1.0 / (ranks + 1.0)))\n",
    "        return {'recall@1': recall_at_1, 'mrr': mrr, 'n': n}\n",
    "\n",
    "    def train(self, epochs, output_dir):\n",
    "        for epoch in range(1, epochs + 1):\n",
    "            self.train_epoch(epoch)\n",
    "            ckpt_dir = os.path.join(output_dir, f\"checkpoint-epoch-{epoch}\")\n",
    "            print(f\"Saving checkpoint to {ckpt_dir}\")\n",
    "            self.model.save(ckpt_dir)\n",
    "\n",
    "            # 每个 epoch 后保存历史到 output_dir\n",
    "            try:\n",
    "                os.makedirs(output_dir, exist_ok=True)\n",
    "                hist_path = os.path.join(output_dir, 'training_history.json')\n",
    "                with open(hist_path, 'w', encoding='utf-8') as hf:\n",
    "                    json.dump(self.history, hf, ensure_ascii=False, indent=2)\n",
    "                print(f\"Saved training history to {hist_path}\")\n",
    "            except Exception as e:\n",
    "                print('保存 training_history 失败:', e)\n",
    "\n",
    "            # 在每个 epoch 之后，如果有验证集则进行评估并保存最优模型（基于 MRR）\n",
    "            if self.val_dataloader is not None:\n",
    "                try:\n",
    "                    eval_res = self.evaluate(eval_max=self.cfg.get('eval_max', 1000), batch_size=self.cfg.get('eval_batch_size', 32))\n",
    "                    self.history['eval'].append(eval_res)\n",
    "                    print(f\"Eval after epoch {epoch}: Recall@1={eval_res['recall@1']:.4f}, MRR={eval_res['mrr']:.4f}\")\n",
    "                    # 保存 best checkpoint（按 mrr）\n",
    "                    if eval_res['mrr'] > self.best_mrr:\n",
    "                        self.best_mrr = eval_res['mrr']\n",
    "                        best_dir = os.path.join(output_dir, 'best_checkpoint')\n",
    "                        print(f\"New best MRR={self.best_mrr:.4f}, saving best checkpoint to {best_dir}\")\n",
    "                        self.model.save(best_dir)\n",
    "                except Exception as e:\n",
    "                    print('在评估时发生错误:', e)\n",
    "\n",
    "\n",
    "# --------------------------- 组装并准备训练（在 notebook 中直接运行） ---------------------------\n",
    "def prepare_and_train(cfg):\n",
    "    train_file = cfg['train_file']\n",
    "    if not os.path.exists(train_file):\n",
    "        raise FileNotFoundError(f\"训练文件不存在: {train_file}. 请先生成 mbpp_train.jsonl\")\n",
    "\n",
    "    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
    "    print('Device:', device)\n",
    "\n",
    "    tokenizer = AutoTokenizer.from_pretrained(cfg['model_path'])\n",
    "    model = EmbeddingModel(cfg['model_path'], temperature=cfg['temperature']).to(device)\n",
    "\n",
    "    dataset = JsonlDataset(train_file)\n",
    "    collate = partial(collate_fn, tokenizer=tokenizer, query_max_len=cfg['query_max_len'], passage_max_len=cfg['passage_max_len'])\n",
    "    dataloader = DataLoader(dataset, batch_size=cfg['batch_size'], shuffle=True, collate_fn=collate, num_workers=cfg['num_workers'])\n",
    "\n",
    "    optimizer = torch.optim.AdamW(model.parameters(), lr=cfg['lr'], weight_decay=cfg['weight_decay'])\n",
    "    total_steps = max(1, len(dataloader) * cfg['epochs'] // cfg['accumulation_steps'])\n",
    "    scheduler = get_cosine_schedule_with_warmup(optimizer, num_warmup_steps=int(0.1*total_steps), num_training_steps=total_steps)\n",
    "\n",
    "    # 尝试查找验证集文件（优先使用 cfg['val_file']，否则常见位置）\n",
    "    val_file = cfg.get('val_file')\n",
    "    if not val_file:\n",
    "        candidate = os.path.join(os.path.dirname(train_file), 'mbpp_val.jsonl')\n",
    "        if os.path.exists(candidate):\n",
    "            val_file = candidate\n",
    "\n",
    "    val_dataloader = None\n",
    "    if val_file and os.path.exists(val_file):\n",
    "        try:\n",
    "            val_dataset = JsonlDataset(val_file)\n",
    "            val_batch = cfg.get('eval_batch_size', max(1, cfg.get('batch_size', 32)))\n",
    "            val_collate = collate\n",
    "            val_dataloader = DataLoader(val_dataset, batch_size=val_batch, shuffle=False, collate_fn=val_collate, num_workers=cfg.get('num_workers', 2))\n",
    "            print(f\"Using val_file for validation: {val_file}, samples={len(val_dataset)}\")\n",
    "        except Exception as e:\n",
    "            print('创建 val_dataloader 失败:', e)\n",
    "\n",
    "    os.makedirs(cfg['output_dir'], exist_ok=True)\n",
    "    trainer = Trainer(model, tokenizer, dataloader, optimizer, scheduler, device, cfg, val_dataloader=val_dataloader)\n",
    "\n",
    "    print('Start training...')\n",
    "    trainer.train(cfg['epochs'], cfg['output_dir'])\n",
    "\n",
    "    final_dir = os.path.join(cfg['output_dir'], 'final_model')\n",
    "    model.save(final_dir)\n",
    "    tokenizer.save_pretrained(final_dir)\n",
    "    print('Training finished. Final model saved to', final_dir)\n",
    "\n",
    "\n",
    "# 注意: 若想立即运行，请取消下一行注释并执行该单元（在资源足够且确认配置无误时）\n",
    "# prepare_and_train(config)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "slocbces9hd",
   "metadata": {},
   "source": [
    "# 模型训练实现\n",
    " \n",
    " 本单元实现了完整的embedding模型微调流程：\n",
    " - 使用SentenceTransformers框架封装BGE-M3模型\n",
    " - 实现in-batch negatives训练策略\n",
    " - 支持混合精度训练(AMP)和梯度累积\n",
    " - 包含数据集类、模型封装、训练器和评估功能\n",
    " - 自动保存训练历史和最佳模型(checkpoint)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "fa9ae4e6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Device: cuda\n",
      "Using val_file for validation: ./mbpp_val.jsonl, samples=86\n",
      "Start training...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1:   0%|          | 0/5 [00:00<?, ?it/s]/tmp/ipykernel_62639/307073869.py:128: FutureWarning: `torch.cuda.amp.autocast(args...)` is deprecated. Please use `torch.amp.autocast('cuda', args...)` instead.\n",
      "  with torch.cuda.amp.autocast(enabled=self.cfg['fp16']):\n",
      "Epoch 1: 100%|██████████| 5/5 [00:11<00:00,  2.20s/it, loss=0.1754, acc=95.24%]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1 finished. avg_loss=0.7287, avg_acc=80.55%\n",
      "Saving checkpoint to ./models/bge-m3-finetuned/checkpoint-epoch-1\n",
      "Saved training history to ./models/bge-m3-finetuned/training_history.json\n",
      "Evaluating on 86 samples, using device cuda ...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  4.82it/s]\n",
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.73it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eval after epoch 1: Recall@1=0.8256, MRR=0.8817\n",
      "New best MRR=0.8817, saving best checkpoint to ./models/bge-m3-finetuned/best_checkpoint\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2: 100%|██████████| 5/5 [00:23<00:00,  4.74s/it, loss=0.1289, acc=95.24%]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 2 finished. avg_loss=0.3898, avg_acc=89.05%\n",
      "Saving checkpoint to ./models/bge-m3-finetuned/checkpoint-epoch-2\n",
      "Saved training history to ./models/bge-m3-finetuned/training_history.json\n",
      "Evaluating on 86 samples, using device cuda ...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.99it/s]\n",
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.75it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eval after epoch 2: Recall@1=0.8023, MRR=0.8653\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3: 100%|██████████| 5/5 [00:22<00:00,  4.44s/it, loss=0.0725, acc=95.24%]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 3 finished. avg_loss=0.3818, avg_acc=88.80%\n",
      "Saving checkpoint to ./models/bge-m3-finetuned/checkpoint-epoch-3\n",
      "Saved training history to ./models/bge-m3-finetuned/training_history.json\n",
      "Evaluating on 86 samples, using device cuda ...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.58it/s]\n",
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.76it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eval after epoch 3: Recall@1=0.8837, MRR=0.9160\n",
      "New best MRR=0.9160, saving best checkpoint to ./models/bge-m3-finetuned/best_checkpoint\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4: 100%|██████████| 5/5 [00:20<00:00,  4.09s/it, loss=0.0156, acc=100.00%]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 4 finished. avg_loss=0.2108, avg_acc=94.75%\n",
      "Saving checkpoint to ./models/bge-m3-finetuned/checkpoint-epoch-4\n",
      "Saved training history to ./models/bge-m3-finetuned/training_history.json\n",
      "Evaluating on 86 samples, using device cuda ...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.77it/s]\n",
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.74it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eval after epoch 4: Recall@1=0.8605, MRR=0.9062\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5: 100%|██████████| 5/5 [00:17<00:00,  3.58s/it, loss=0.0001, acc=100.00%]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 5 finished. avg_loss=0.0934, avg_acc=97.25%\n",
      "Saving checkpoint to ./models/bge-m3-finetuned/checkpoint-epoch-5\n",
      "Saved training history to ./models/bge-m3-finetuned/training_history.json\n",
      "Evaluating on 86 samples, using device cuda ...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.48it/s]\n",
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.73it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eval after epoch 5: Recall@1=0.8605, MRR=0.9034\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6: 100%|██████████| 5/5 [00:23<00:00,  4.76s/it, loss=0.0005, acc=100.00%]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 6 finished. avg_loss=0.0771, avg_acc=96.75%\n",
      "Saving checkpoint to ./models/bge-m3-finetuned/checkpoint-epoch-6\n",
      "Saved training history to ./models/bge-m3-finetuned/training_history.json\n",
      "Evaluating on 86 samples, using device cuda ...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  9.45it/s]\n",
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.66it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eval after epoch 6: Recall@1=0.8256, MRR=0.8812\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7: 100%|██████████| 5/5 [00:13<00:00,  2.66s/it, loss=0.0967, acc=95.24%] \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 7 finished. avg_loss=0.0810, avg_acc=97.55%\n",
      "Saving checkpoint to ./models/bge-m3-finetuned/checkpoint-epoch-7\n",
      "Saved training history to ./models/bge-m3-finetuned/training_history.json\n",
      "Evaluating on 86 samples, using device cuda ...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  8.88it/s]\n",
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.70it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eval after epoch 7: Recall@1=0.8372, MRR=0.8846\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 8: 100%|██████████| 5/5 [00:24<00:00,  4.81s/it, loss=0.3463, acc=95.24%] \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 8 finished. avg_loss=0.1127, avg_acc=97.80%\n",
      "Saving checkpoint to ./models/bge-m3-finetuned/checkpoint-epoch-8\n",
      "Saved training history to ./models/bge-m3-finetuned/training_history.json\n",
      "Evaluating on 86 samples, using device cuda ...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  9.04it/s]\n",
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.84it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eval after epoch 8: Recall@1=0.8372, MRR=0.8855\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 9: 100%|██████████| 5/5 [00:19<00:00,  3.91s/it, loss=0.0033, acc=100.00%]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 9 finished. avg_loss=0.0694, avg_acc=97.25%\n",
      "Saving checkpoint to ./models/bge-m3-finetuned/checkpoint-epoch-9\n",
      "Saved training history to ./models/bge-m3-finetuned/training_history.json\n",
      "Evaluating on 86 samples, using device cuda ...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  9.14it/s]\n",
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.72it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eval after epoch 9: Recall@1=0.8372, MRR=0.8895\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10: 100%|██████████| 5/5 [00:19<00:00,  3.98s/it, loss=0.0009, acc=100.00%]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 10 finished. avg_loss=0.0269, avg_acc=99.00%\n",
      "Saving checkpoint to ./models/bge-m3-finetuned/checkpoint-epoch-10\n",
      "Saved training history to ./models/bge-m3-finetuned/training_history.json\n",
      "Evaluating on 86 samples, using device cuda ...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.30it/s]\n",
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.68it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eval after epoch 10: Recall@1=0.8372, MRR=0.8886\n",
      "Training finished. Final model saved to ./models/bge-m3-finetuned/final_model\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "# 设置tokenizers并行ism以避免DataLoader多进程警告\n",
    "os.environ[\"TOKENIZERS_PARALLELISM\"] = \"false\"\n",
    "\n",
    "config = {\n",
    "    \"train_file\": \"./mbpp_train.jsonl\",\n",
    "    \"model_path\": \"./bge-m3\",\n",
    "    \"output_dir\": \"./models/bge-m3-finetuned\",\n",
    "    \"epochs\": 10,\n",
    "    \"batch_size\": 80,\n",
    "    \"query_max_len\": 512,\n",
    "    \"passage_max_len\": 512,\n",
    "    \"lr\": 2e-4,\n",
    "    \"accumulation_steps\": 2,\n",
    "    \"fp16\": True,  # 是否启用混合精度\n",
    "    \"weight_decay\": 0.01,\n",
    "    \"num_workers\": 2,\n",
    "    \"temperature\": 0.02\n",
    "}\n",
    "\n",
    "prepare_and_train(config)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ikbf4guc9b",
   "metadata": {},
   "source": [
    "# 训练配置与执行\n",
    " \n",
    " 本单元配置并启动模型训练：\n",
    " - 设置训练参数：学习率、批大小、训练轮数等\n",
    " - 配置模型路径和数据路径\n",
    " - 调用训练函数开始微调BGE-M3模型\n",
    " - 训练过程中会自动保存每个epoch的checkpoint和最佳模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "d560d170",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "使用评估文件: ./mbpp_val.jsonl\n",
      "Device for encoding: cuda\n",
      "\n",
      "加载模型 baseline from ./models/bge-m3-finetuned/final_model ...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 3/3 [00:00<00:00, 21.07it/s]\n",
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.69it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "加载模型 bge_m3 from ./bge-m3 ...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.28it/s]\n",
      "Batches: 100%|██████████| 3/3 [00:00<00:00,  7.82it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "=== 评估结果对比 ===\n",
      "baseline: n=86, Recall@1=0.8372, MRR=0.8886\n",
      "bge_m3: n=86, Recall@1=0.7791, MRR=0.8380\n",
      "\n",
      "增益（bge_m3 - baseline）:\n",
      "Recall@1 增益: -0.0581\n",
      "MRR 增益: -0.0507\n",
      "\n",
      "评估完成\n",
      "Saved eval results to ./models/bge-m3-finetuned/eval_results.json\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "# 评估单元：将微调后模型作为 baseline，bge-m3（未微调）作为对比\n",
    "# 说明：本单元会从训练数据或已加载变量中构建评估集合，使用 SentenceTransformer 对 query 和 passage 进行编码并计算指标。\n",
    "import os\n",
    "# 设置tokenizers并行ism以避免DataLoader多进程警告\n",
    "os.environ[\"TOKENIZERS_PARALLELISM\"] = \"false\"\n",
    "\n",
    "import json\n",
    "import random\n",
    "import numpy as np\n",
    "import torch\n",
    "from sentence_transformers import SentenceTransformer\n",
    "from tqdm.auto import tqdm\n",
    "\n",
    "# 可配置项\n",
    "EVAL_MAX = 1000  # 评估样本上限，减小以便快速测试\n",
    "SEED = 42\n",
    "\n",
    "# 尝试定位评估数据文件（优先使用验证集/指定的 eval file）\n",
    "eval_candidates = []\n",
    "if isinstance(config, dict):\n",
    "    if config.get('eval_file'):\n",
    "        eval_candidates.append(config.get('eval_file'))\n",
    "    # keep train_file as fallback\n",
    "    if config.get('train_file'):\n",
    "        eval_candidates.append(config.get('train_file'))\n",
    "\n",
    "# 如果之前单元定义了 out_val 或 out_train 变量，也加入候选（更靠前）\n",
    "if 'out_val' in globals():\n",
    "    eval_candidates.insert(0, out_val)\n",
    "if 'out_train' in globals():\n",
    "    eval_candidates.append(out_train)\n",
    "\n",
    "# 最后加入可能的绝对路径（验证优先，训练为最后退路）\n",
    "eval_candidates.extend([\n",
    "    \"./mbpp_val.jsonl\",\n",
    "    \"./mbpp_train.jsonl\",\n",
    "])\n",
    "\n",
    "train_file = None\n",
    "for p in eval_candidates:\n",
    "    if not p:\n",
    "        continue\n",
    "    if os.path.exists(p):\n",
    "        train_file = p\n",
    "        break\n",
    "\n",
    "if train_file is None:\n",
    "    raise FileNotFoundError('未找到可用于评估的文件（尝试过 eval/train 路径），请先生成 mbpp_val.jsonl 或 mbpp_train.jsonl')\n",
    "print('使用评估文件:', train_file)\n",
    "\n",
    "# 读取 samples（jsonl）\n",
    "samples = []\n",
    "with open(train_file, 'r', encoding='utf-8') as f:\n",
    "    for line in f:\n",
    "        line = line.strip()\n",
    "        if not line:\n",
    "            continue\n",
    "        samples.append(json.loads(line))\n",
    "\n",
    "if len(samples) == 0:\n",
    "    raise ValueError('评估文件中未读到样本')\n",
    "\n",
    "# 采样子集用于快速评估\n",
    "random.seed(SEED)\n",
    "if len(samples) > EVAL_MAX:\n",
    "    samples = random.sample(samples, EVAL_MAX)\n",
    "\n",
    "queries = [s.get('query') or s.get('prompt') or s.get('text') or '' for s in samples]\n",
    "pos_docs = [s.get('pos_doc') or s.get('code') or '' for s in samples]\n",
    "\n",
    "# 准备模型路径：我们把微调后的模型作为 baseline，未微调的 bge-m3 作为对比\n",
    "bge_unfinetuned_path = config.get('model_path') if isinstance(config, dict) else './bge-m3'\n",
    "finetuned_dir = os.path.join(config.get('output_dir'), 'final_model') if isinstance(config, dict) else None\n",
    "\n",
    "models_to_check = []\n",
    "# baseline 指向微调后模型\n",
    "if finetuned_dir and os.path.exists(finetuned_dir):\n",
    "    models_to_check.append((\"baseline\", finetuned_dir))\n",
    "else:\n",
    "    print(f\"未检测到微调后模型目录: {finetuned_dir}，baseline 无法指向微调模型\")\n",
    "\n",
    "# 对比模型：bge-m3（未微调）\n",
    "if bge_unfinetuned_path and os.path.exists(bge_unfinetuned_path):\n",
    "    models_to_check.append((\"bge_m3\", bge_unfinetuned_path))\n",
    "else:\n",
    "    print(f\"未检测到未微调模型目录: {bge_unfinetuned_path}\")\n",
    "\n",
    "if len(models_to_check) == 0:\n",
    "    raise FileNotFoundError('未找到任何可评估的模型路径')\n",
    "\n",
    "# 设备设置\n",
    "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n",
    "print('Device for encoding:', device)\n",
    "\n",
    "# 评估函数\n",
    "\n",
    "def evaluate_model(name, model_path, queries, pos_docs, device=device, batch_size=32):\n",
    "    print(f\"\\n加载模型 {name} from {model_path} ...\")\n",
    "    s = SentenceTransformer(model_path, device=device, trust_remote_code=True)\n",
    "\n",
    "    # 编码（返回 torch tensor）\n",
    "    q_emb = s.encode(queries, batch_size=batch_size, convert_to_tensor=True, show_progress_bar=True)\n",
    "    p_emb = s.encode(pos_docs, batch_size=batch_size, convert_to_tensor=True, show_progress_bar=True)\n",
    "\n",
    "    q_emb = torch.nn.functional.normalize(q_emb, p=2, dim=-1)\n",
    "    p_emb = torch.nn.functional.normalize(p_emb, p=2, dim=-1)\n",
    "\n",
    "    sim = (q_emb @ p_emb.T).cpu().numpy()\n",
    "\n",
    "    n = sim.shape[0]\n",
    "    ranks = []\n",
    "    for i in range(n):\n",
    "        order = np.argsort(-sim[i])\n",
    "        rank = int(np.where(order == i)[0][0])\n",
    "        ranks.append(rank)\n",
    "\n",
    "    ranks = np.array(ranks)\n",
    "    recall_at_1 = np.mean(ranks == 0)\n",
    "    mrr = np.mean(1.0 / (ranks + 1.0))\n",
    "    return {'recall@1': float(recall_at_1), 'mrr': float(mrr), 'n': int(n)}\n",
    "\n",
    "# 逐个模型评估\n",
    "results = {}\n",
    "for name, path in models_to_check:\n",
    "    try:\n",
    "        results[name] = evaluate_model(name, path, queries, pos_docs)\n",
    "    except Exception as e:\n",
    "        print(f\"评估模型 {name} 时发生错误: {e}\")\n",
    "\n",
    "# 打印比较结果\n",
    "print('\\n=== 评估结果对比 ===')\n",
    "for name, res in results.items():\n",
    "    print(f\"{name}: n={res['n']}, Recall@1={res['recall@1']:.4f}, MRR={res['mrr']:.4f}\")\n",
    "\n",
    "# 如果同时有 baseline（微调）和 bge_m3（未微调），打印增益：对比模型 - baseline\n",
    "if 'baseline' in results and 'bge_m3' in results:\n",
    "    bas = results['baseline']\n",
    "    bge = results['bge_m3']\n",
    "    print('\\n增益（bge_m3 - baseline）:')\n",
    "    print(f\"Recall@1 增益: {bge['recall@1'] - bas['recall@1']:.4f}\")\n",
    "    print(f\"MRR 增益: {bge['mrr'] - bas['mrr']:.4f}\")\n",
    "\n",
    "print('\\n评估完成')\n",
    "\n",
    "# 保存 eval 结果\n",
    "try:\n",
    "    out_dir = config.get('output_dir') if isinstance(config, dict) else './models/bge-m3-finetuned'\n",
    "    os.makedirs(out_dir, exist_ok=True)\n",
    "    eval_save_path = os.path.join(out_dir, 'eval_results.json')\n",
    "    with open(eval_save_path, 'w', encoding='utf-8') as ef:\n",
    "        json.dump(results, ef, ensure_ascii=False, indent=2)\n",
    "    print('Saved eval results to', eval_save_path)\n",
    "except Exception as e:\n",
    "    print('保存 eval_results.json 失败:', e)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37zgz9gr423",
   "metadata": {},
   "source": [
    "# 模型评估与对比\n",
    " \n",
    " 本单元对训练后的模型进行评估：\n",
    " - 加载微调后的模型(baseline)和原始BGE-M3模型进行对比\n",
    " - 使用验证集计算Recall@1和MRR指标\n",
    " - 比较微调前后模型的性能差异\n",
    " - 保存评估结果到eval_results.json文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "577c4268",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loaded history from ./models/bge-m3-finetuned/training_history.json\n",
      "steps: 50, epochs: 10\n",
      "Loaded eval results from ./models/bge-m3-finetuned/eval_results.json\n"
     ]
    },
    {
     "data": {
      "image/png": "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kpOTxeOePHmCjIwMmJmZifsq+vK3YMEC2NvbY9CgQcjLywMAmJubo2XLlsjJyRFfubm5CknQ822pq6vDx8cHly9fRnx8PFJTU/HVV1/V50dBjYAgCJg1axYuXryIY8eOQVdXV9khEREREdWK0pOK5s2bw8LCAj/88APKysoQHh6OsLCwV9JXt27dIJfLERwcDCcnJ6ioqMDBwQHffvutOPUJADw8PLBx40Zcv34dxcXF8PX1hampKXr16lVp+6qqqti5cydsbGwwcOBA5ObmomfPnrCwsICvry/y8/MhCAJSUlJw9OjRl7Zz6tQpxMbGQi6XQ1tbG02bNuWKUG8gb29vREVF4fjx49DT01N2OERERES1pvSkAgB27tyJXbt2QVdXF9u2bcPYsWNfST+qqqro168fpFIp2rdvDwD44IMPkJeXp5BUTJw4EbNnz4aLiwuMjIxw+fJlHD58uFpf7FVUVPDdd9+hW7duGDBgAPLy8nD48GGkp6fD2toaurq6GDJkCBITE1/axp07dzBu3DjIZDK0atUKurq6WLJkSd0/AGo0UlJSsHnzZiQkJMDS0hISiQQSiQReXl7KDo2IiIioxlQEQRCqqhQTE4Pu3bsjOjoadnZ2DREXveGCg4Ph4eHBa4qIiIiokapJDtAoRiqIiIiIiOj19UYlFREREeI0kudf5c+jICIiIiKi+vVG3f3r4OBQraVliYiIiIio/rxRIxVERERERNTwajRSER8f/6rioLdMUlISAF5TRERERI1VTb6nVWv1p9TUVFhbWys8oI6ortTU1BSeLE5EREREjYuWlhbi4+NhYWFRab1qJRXA08Ti/v379RIcEQAUFxdDU1NT2WEQERER0UuUP6i6KtVOKoiIiIiIiCrCG7WJiIiIiKhOmFQQEREREVGdMKkgIiIiIqI6YVJBRERERER1wqSCiIiIiIjqhEkFERERERHVCZMKIiIiIiKqk/8HpJwaaFGrhroAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 800x234 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABYMAAAJjCAYAAABeEQ6PAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Xd8U/X+x/F3dlu6aMtoWUU2iFREvIIouJlexxXHlelAUBQcCKi4rlwX4mBdQcCr14n6wwXiYggqCHWB4mjZe5Xupjm/P9KkhLY0LW2TtK/n49FHk5OT5JPT6knffPL5mgzDMAQAAAAAAAAAqNXMgS4AAAAAAAAAAFD9CIMBAAAAAAAAoA4gDAYAAAAAAACAOoAwGAAAAAAAAADqAMJgAAAAAAAAAKgDCIMBAAAAAAAAoA4gDAYAAAAAAACAOoAwGAAAAAAAAADqAMJgAAAAAAAAAKgDCIOBIPDtt9/q8ssvV/PmzeVwONSoUSOdffbZuuuuu3z2mzlzphYsWBCYIouYTCY99NBDAa0BABD6FixYIJPJVObXV199FdD60tPTZTKZ9PTTTwe0Dn9U5v3BV199FRTHGQCCUSDPUb1791bv3r2r7fElaePGjXrooYeUnp5e4rZhw4YpOTm5Wp8fJdXEzx3wsAa6AKCu++ijjzRo0CD17t1bTz75pBITE7Vr1y6tW7dOb7zxhp555hnvvjNnzlRCQoKGDRsWuIIBAKhC8+fPV/v27Uts79ixYwCqCU2VeX/QtWtXrVmzhuMMACdQW89RGzdu1MMPP6zevXuXCH4feOAB3XHHHYEprA6bOXNmoEtAHUIYDATYk08+qZYtW2rp0qWyWov/k7zmmmv05JNPBrAyAACq36mnnqpu3boFuow6o6CgQCaTSdHR0frb3/4W6HIAIKjVxXNUq1atAl1CnZKdna2IiIiQ/wcGhBbGRAABduDAASUkJPgEwR5mc/F/osnJyfrll1+0fPly78eTjv1X3IyMDN19991q2bKl7Ha7mjRpojvvvFNZWVk+j2kymXTbbbdpzpw5atu2rRwOhzp27Kg33nij0q/h559/1mWXXab69esrLCxMKSkpWrhwoc8+LpdLjz32mNq1a6fw8HDFxsbqtNNO03PPPefdZ9++fbr55pvVrFkzORwONWjQQD179tRnn33m81ifffaZLrjgAkVHRysiIkI9e/bU559/7rOPv48FAAh+FTl3+XNOkqTDhw/rrrvu0imnnCKHw6GGDRuqX79++vXXX0vsO23aNLVs2VKRkZE6++yz9c0335Rbs+cjxl988YVuuukmxcfHKzo6WkOGDFFWVpZ2796tq6++WrGxsUpMTNTdd9+tgoICn8fIz8/XY489pvbt23vPZcOHD9e+ffu8+5zo/YFnFMR///tf3XXXXWrSpIkcDof++OOPMsdEfPvttxo4cKDi4+MVFhamVq1a6c477/TezvkVAIqdfvrp6tWrV4nthYWFatKkia644grvtocfflhnnXWW4uLiFB0dra5du2revHkyDOOEz1HW/68944yOHRO0bt06XXPNNUpOTlZ4eLiSk5N17bXXasuWLd59FixYoH/84x+SpD59+njPHZ7HKW1MRG5uriZOnOjzt+aYMWN0+PBhn/2Sk5M1YMAALVmyRF27dlV4eLjat2+vl19++YSv0SMvL0+PPPKIOnTooLCwMMXHx6tPnz5avXp1pWv58MMPdfrppys8PFwdOnTQhx9+6D0OHTp0UL169dS9e3etW7fO5/7Dhg1TZGSkfvnlF11wwQWqV6+eGjRooNtuu03Z2dk++86YMUPnnnuuGjZsqHr16qlz58568sknS5zXe/furVNPPVUrVqxQjx49FBERoREjRnhvO35MxKxZs9SlSxdFRkYqKipK7du316RJk3z28ed9j+d36PXXX9fkyZOVlJSk6OhoXXjhhfrtt9/8+tmgdqEzGAiws88+W3PnztXYsWN1/fXXq2vXrrLZbCX2e++993TVVVcpJibG+xESh8Mhyf2vieedd562b9+uSZMm6bTTTtMvv/yiBx98UD/99JM+++wzmUwm72MtXrxYX375pR555BHVq1dPM2fO1LXXXiur1aqrrrqqQvX/9ttv6tGjhxo2bKjnn39e8fHxevXVVzVs2DDt2bNH9957ryR3B/RDDz2k+++/X+eee64KCgr066+/+py0b7jhBq1fv17/+te/1LZtWx0+fFjr16/XgQMHvPu8+uqrGjJkiC677DItXLhQNptNc+bM0SWXXKKlS5fqggsu8PuxAACBV1hYKKfT6bPNZDLJYrH4bPPn3OXvOeno0aM655xzlJ6ergkTJuiss85SZmamVqxYoV27dvl8JHjGjBlq3769pk+fLsn98dl+/fopLS1NMTEx5b6+G2+8UVdccYXeeOMNbdiwQZMmTZLT6dRvv/2mK664QjfffLM+++wzPfHEE0pKStL48eMluf8R9bLLLtPKlSt17733qkePHtqyZYumTJmi3r17a926dQoPDz/h+wOPiRMn6uyzz9bs2bNlNpvVsGFD7d69u0StS5cu1cCBA9WhQwdNmzZNzZs3V3p6uj799FPvPpxfAdQl5Z2jhg8frjvuuEO///672rRp493n008/1c6dOzV8+HDvtvT0dN1yyy1q3ry5JOmbb77R7bffrh07dujBBx+sknrT09PVrl07XXPNNYqLi9OuXbs0a9YsnXnmmdq4caMSEhLUv39/Pf7445o0aZJmzJihrl27Siq7I9gwDP3973/X559/rokTJ6pXr1768ccfNWXKFK1Zs0Zr1qzxOe/88MMPuuuuu3TfffepUaNGmjt3rkaOHKnWrVvr3HPPLbN2p9Opvn37auXKlbrzzjt1/vnny+l06ptvvtHWrVvVo0ePStUyceJETZ48WTExMXr44Yd1xRVXaOLEifr888/1+OOPy2QyacKECRowYIDS0tIUHh7uvX9BQYH69eunW265Rffdd59Wr16txx57TFu2bNEHH3zg3e/PP//Udddd5w2of/jhB/3rX//Sr7/+WiII37Vrl/75z3/q3nvv1eOPP+7TAHasN954Q6NHj9btt9+up59+WmazWX/88Yc2btzo3cff9z0ekyZNUs+ePTV37lxlZGRowoQJGjhwoDZt2lTifRdqOQNAQO3fv98455xzDEmGJMNmsxk9evQwpk6dahw9etRn306dOhnnnXdeiceYOnWqYTabjbVr1/psf+eddwxJxscff+zdJskIDw83du/e7d3mdDqN9u3bG61bty63XknGlClTvNevueYaw+FwGFu3bvXZr2/fvkZERIRx+PBhwzAMY8CAAUZKSsoJHzsyMtK48847y7w9KyvLiIuLMwYOHOizvbCw0OjSpYvRvXt3vx8LABBY8+fP9577jv+yWCw++/p77vL3nPTII48Ykoxly5aVWV9aWpohyejcubPhdDq927/77jtDkvH666/79fpuv/12n+1///vfDUnGtGnTfLanpKQYXbt29V5//fXXDUnGokWLfPZbu3atIcmYOXOmd1tZ7w++/PJLQ5Jx7rnnlnnbl19+6d3WqlUro1WrVkZOTk6Zr4vzK4C6wN9z1P79+w273W5MmjTJ5/5XX3210ahRI6OgoKDUxy8sLDQKCgqMRx55xIiPjzdcLpf3tvPOO8/n/+ml/f/aMIrPU/Pnzy/zdTidTiMzM9OoV6+e8dxzz3m3v/3226U+pmEYxtChQ40WLVp4ry9ZssSQZDz55JM++7355puGJOM///mPd1uLFi2MsLAwY8uWLd5tOTk5RlxcnHHLLbeUWadhGMYrr7xiSDJeeumlMvepaC3h4eHG9u3bvdtSU1MNSUZiYqKRlZXl3f7+++8bkozFixf7HAdJPsfNMAzjX//6lyHJWLVqVak1en62r7zyimGxWIyDBw96bzvvvPMMScbnn39e4n7H/9xvu+02IzY2tsxjYRj+v+/x/A7169fPZ7+33nrLkGSsWbPmhM+D2ocxEUCAxcfHa+XKlVq7dq3+/e9/67LLLtPmzZs1ceJEde7cWfv37y/3MT788EOdeuqpSklJkdPp9H5dcsklpX6k6IILLlCjRo281y0WiwYPHqw//vhD27dvr1D9X3zxhS644AI1a9bMZ/uwYcOUnZ2tNWvWSJK6d++uH374QaNHj9bSpUuVkZFR4rG6d++uBQsW6LHHHtM333xT4mM1q1ev1sGDBzV06FCf1+lyuXTppZdq7dq13rEY5T0WACA4vPLKK1q7dq3P17fffltiP3/OXf6ekz755BO1bdtWF154Ybn19e/f36db5rTTTpMkn4/cnsiAAQN8rnfo0MH7uMdvP/YxP/zwQ8XGxmrgwIE+57yUlBQ1bty4QivZX3nlleXus3nzZv35558aOXKkwsLCytyP8yuAuqS8c1R8fLwGDhyohQsXyuVySZIOHTqk//u//9OQIUN8RgF+8cUXuvDCCxUTEyOLxSKbzaYHH3xQBw4c0N69e6uk3szMTE2YMEGtW7eW1WqV1WpVZGSksrKytGnTpko95hdffCFJJRYp/cc//qF69eqVGNeXkpLi7X6WpLCwMLVt27bc8+Ynn3yisLAw79iEqqqlSZMm3uuec3Dv3r0VERFRYntpNV5//fU+16+77jpJ0pdffundtmHDBg0aNEjx8fHen+2QIUNUWFiozZs3+9y/fv36Ov/888t8jR7du3fX4cOHde211+r//u//Ss0F/H3f4zFo0CCf6xV9T4PagzAYCBLdunXThAkT9Pbbb2vnzp0aN26c0tPT/VpEbs+ePfrxxx9ls9l8vqKiomQYRokTR+PGjUs8hmdbRT/meeDAASUmJpbYnpSU5PN4EydO1NNPP61vvvlGffv2VXx8vC644AKf2Uxvvvmmhg4dqrlz5+rss89WXFychgwZ4v0o6549eyRJV111VYnX+sQTT8gwDB08eNCvxwIABIcOHTqoW7duPl9nnHFGif38OXf5e07at2+fmjZt6ld98fHxPtc9Hz/Nycnx6/5xcXE+1+12e5nbc3Nzvdf37Nmjw4cPy263lzjn7d69269/LPYo7ZgczzOHuLzjwvkVQF3izzlqxIgR2rFjh5YtWyZJev3115WXl+cTWH733Xe6+OKLJUkvvfSSvv76a61du1aTJ0+W5P85pTzXXXedXnzxRd14441aunSpvvvuO61du1YNGjSo9HMcOHBAVqtVDRo08NluMpnUuHHjEn8/Hn/elNznzvKef9++fUpKSipzbEJlaqnIOViSz3lYkqxWa4nXc/x7j61bt6pXr17asWOHnnvuOW+j14wZMySV/Nn6c06W3GOZXn75ZW3ZskVXXnmlGjZsqLPOOsv7e+apwZ/3PR4n+54GtQczg4EgZLPZNGXKFD377LP6+eefy90/ISFB4eHhZQ7mT0hI8Lle2h9snm2lnbxPJD4+Xrt27SqxfefOnT7PbbVaNX78eI0fP16HDx/WZ599pkmTJumSSy7Rtm3bFBERoYSEBE2fPl3Tp0/X1q1btXjxYt13333au3evlixZ4n2sF154ocwV0D1dY+U9FgAgtPhz7vL3nNSgQYMKfxKmpiUkJCg+Pr7Mc1ZUVJTfj3XsugFl8fxhXd5x4fwKAL4uueQSJSUlaf78+brkkks0f/58nXXWWerYsaN3nzfeeEM2m00ffvihz6cv3n///XIf37N/Xl6ez/bj/1HwyJEj+vDDDzVlyhTdd9993u15eXnehpnKiI+Pl9Pp1L59+3xCWMMwtHv3bp155pmVfuxjNWjQQKtWrZLL5SozEK6pWjycTqcOHDjg8zfy8e893n//fWVlZendd99VixYtvPulpqaW+pj+nJM9hg8fruHDhysrK0srVqzQlClTNGDAAG3evFktWrTw+30PcDw6g4EAK+1/3pK8H+Px/KueVPa/qA4YMEB//vmn4uPjS/zLdbdu3UqsBvv55597u2wl98IIb775plq1auV3p5THBRdcoC+++MJ7wvF45ZVXFBERUWpoGxsbq6uuukpjxozRwYMHlZ6eXmKf5s2b67bbbtNFF12k9evXS5J69uyp2NhYbdy4sdTX2a1bN++/6pb3WACA0OLPucvfc1Lfvn21efNm78dNg9GAAQN04MABFRYWlnq+a9eunXdffzquytO2bVu1atVKL7/8conAoSycXwHAPbbohhtu0Pvvv6+VK1dq3bp1JUYdmEwmWa1Wn7FDOTk5+u9//1vu43v+lvvxxx99ti9evLjEcxiGUWIR0blz56qwsNBnW0U6Qj0LdL/66qs+2xctWqSsrCzv7Serb9++ys3N1YIFCwJey7Fee+01n+v/+9//JLlHTUjF4e6xx90wDL300ktVVkO9evXUt29fTZ48Wfn5+frll18kVe5vcUCiMxgIuEsuuURNmzbVwIED1b59e7lcLqWmpuqZZ55RZGSk7rjjDu++nTt31htvvKE333xTp5xyisLCwtS5c2fdeeedWrRokc4991yNGzdOp512mlwul7Zu3apPP/1Ud911l8466yzv4yQkJOj888/XAw884F2R/ddff9Ubb7xR4fqnTJmiDz/8UH369NGDDz6ouLg4vfbaa/roo4/05JNPeldaHzhwoE499VR169ZNDRo00JYtWzR9+nS1aNFCbdq00ZEjR9SnTx9dd911at++vaKiorR27VotWbJEV1xxhSQpMjJSL7zwgoYOHaqDBw/qqquuUsOGDbVv3z798MMP2rdvn2bNmuXXYwEAgsPPP/9cYqV2yb2q+bFdP/6cu/w9J91555168803ddlll+m+++5T9+7dlZOTo+XLl2vAgAHq06dP9b/wclxzzTV67bXX1K9fP91xxx3q3r27bDabtm/fri+//FKXXXaZLr/8ckllvz+oqBkzZmjgwIH629/+pnHjxql58+baunWrli5dqtdee43zK4A6x99z1IgRI/TEE0/ouuuuU3h4uAYPHuyzf//+/TVt2jRdd911uvnmm3XgwAE9/fTTJYLb0jRu3FgXXnihpk6dqvr166tFixb6/PPP9e677/rsFx0drXPPPVdPPfWUEhISlJycrOXLl2vevHmKjY312ffUU0+VJP3nP/9RVFSUwsLC1LJly1I/JXrRRRfpkksu0YQJE5SRkaGePXvqxx9/1JQpU3T66afrhhtuKPc1+OPaa6/V/PnzNWrUKP3222/q06ePXC6Xvv32W3Xo0EHXXHNNjdXiYbfb9cwzzygzM1NnnnmmVq9erccee0x9+/bVOeecI8l9fOx2u6699lrde++9ys3N1axZs3To0KGTeu6bbrpJ4eHh6tmzpxITE7V7925NnTpVMTEx3g5of9/3ACUEcvU6AO6VT6+77jqjTZs2RmRkpGGz2YzmzZsbN9xwg7Fx40affdPT042LL77YiIqKMiT5rPKamZlp3H///Ua7du0Mu91uxMTEGJ07dzbGjRvns/q6JGPMmDHGzJkzjVatWhk2m81o37698dprr/lVryRjypQpPtt++uknY+DAgUZMTIxht9uNLl26lFjV9plnnjF69OhhJCQkGHa73WjevLkxcuRIIz093TAMw8jNzTVGjRplnHbaaUZ0dLQRHh5utGvXzpgyZYrPSq+GYRjLly83+vfvb8TFxRk2m81o0qSJ0b9/f+Ptt9+u8GMBAALjRCu167jVxCty7vLnnGQYhnHo0CHjjjvuMJo3b27YbDajYcOGRv/+/Y1ff/3VMIziVdqfeuqpEvct7VxY1utbu3atz/YpU6YYkox9+/b5bB86dKhRr149n20FBQXG008/bXTp0sUICwszIiMjjfbt2xu33HKL8fvvv3v3K+v9gWf1cM/58VhlrU6/Zs0ao2/fvkZMTIzhcDiMVq1aGePGjTMMg/MrgLqjIucojx49ehiSjOuvv77Ux3z55ZeNdu3aGQ6HwzjllFOMqVOnGvPmzTMkGWlpad79zjvvPOO8887zue+uXbuMq666yoiLizNiYmKMf/7zn8a6desMST7nuO3btxtXXnmlUb9+fSMqKsq49NJLjZ9//tlo0aKFMXToUJ/HnD59utGyZUvDYrH4PM7QoUN9/s40DMPIyckxJkyYYLRo0cKw2WxGYmKiceuttxqHDh3y2a9FixZG//79S7z20l5TaXJycowHH3zQaNOmjWG32434+Hjj/PPPN1avXl1ltXjeUxyrtHO+57z8448/Gr179zbCw8ONuLg449ZbbzUyMzN97v/BBx94z9VNmjQx7rnnHuOTTz4pcZ4977zzjE6dOpX62o8/RgsXLjT69OljNGrUyLDb7UZSUpJx9dVXGz/++KPP/fx531PW+wHP6y7tfRJqN5NhGEZ1B84AgofJZNKYMWP04osvBroUAAD8wrkLAADUpGHDhumdd95RZmZmoEsBqhwzgwEAAAAAAACgDiAMBgAAAAAAAIA6gDERAAAAAAAAAFAH0BkMAAAAAKgVVqxYoYEDByopKUkmk0nvv/9+ufdZvny5zjjjDIWFhemUU07R7Nmzq79QAAAChDAYAAAAAFArZGVlqUuXLn4vOJmWlqZ+/fqpV69e2rBhgyZNmqSxY8dq0aJF1VwpAACBwZgIAAAAAECtYzKZ9N577+nvf/97mftMmDBBixcv1qZNm7zbRo0apR9++EFr1qypgSoBAKhZ1kAXUNNcLpd27typqKgomUymQJcDAKijDMPQ0aNHlZSUJLM5OD+owzkTABBo1X2+XLNmjS6++GKfbZdcconmzZungoIC2Wy2EvfJy8tTXl6e97rL5dLBgwcVHx/P+RIAEDD+njPrXBi8c+dONWvWLNBlAAAgSdq2bZuaNm0a6DJKxTkTABAsqut8uXv3bjVq1MhnW6NGjeR0OrV//34lJiaWuM/UqVP18MMPV3ktAABUhfLOmXUuDI6KipLkPjDR0dEBrgYAUFdlZGSoWbNm3vNSMOKcCQAItJo4Xx7fzeuZpFhWl+/EiRM1fvx47/UjR46oefPmnC8BAAHl7zmzzoXBnhN6dHQ0J2oAQMAF88dJOWcCAIJFdZ0vGzdurN27d/ts27t3r6xWq+Lj40u9j8PhkMPhKLGd8yUAIBiUd84MziGFAAAAAABUs7PPPlvLli3z2fbpp5+qW7dupc4LBgAg1BEGAwAAAABqhczMTKWmpio1NVWSlJaWptTUVG3dulWSe8TDkCFDvPuPGjVKW7Zs0fjx47Vp0ya9/PLLmjdvnu6+++5AlA8AQLWrc2MiAAAAAAC107p169SnTx/vdc9s36FDh2rBggXatWuXNxiWpJYtW+rjjz/WuHHjNGPGDCUlJen555/XlVdeWeO1AwBQEwiDAQBApRmGIafTqcLCwkCXgmpmsVhktVqDes41APTu3du7AFxpFixYUGLbeeedp/Xr11djVQAQHHjvHtqq6v04YTAAAKiU/Px87dq1S9nZ2YEuBTUkIiJCiYmJstvtgS4FAAAAFcB799qhKt6PEwYDAIAKc7lcSktLk8ViUVJSkux2Ox2jtZhhGMrPz9e+ffuUlpamNm3ayGxm6QkAAIBQwHv30FeV78cJgwEAQIXl5+fL5XKpWbNmioiICHQ5qAHh4eGy2WzasmWL8vPzFRYWFuiSAAAA4Afeu9cOVfV+nJYOAABQaXSH1i38vAEAAEIX7+VCX1X8DPktAAAAAAAAAIA6gDAYAAAAAAAAAOoAZgYDAIDAcRVKW1ZLmXukyEZSix6S2RLoqqrVV199pT59+ujQoUOKjY2t8P0feughvf/++0pNTa3y2gAAAFC3zBj1RY0+35jZ59fo81WF5ORk3XnnnbrzzjslSSaTSe+9957+/ve/B7SuyqIzGAAABMbGxdL0U6WFA6RFI93fp5/q3g4AAACgzhs2bJhMJpNMJpOsVquaN2+uW2+9VYcOHQp0aSXs2LFD9913n1JSUpSQkKBTTjlFV199tT777LNS97/jjjt0xhlnyOFwKCUlpcbqJAwGACAErFixQgMHDlRSUpJMJpPef//9cu+zfPlynXHGGQoLC9Mpp5yi2bNnV3+h/tq4WHpriJSx03d7xi73dgJhAAAAAJIuvfRS7dq1S+np6Zo7d64++OADjR49OtBl+fjf//6njh07asuWLZoyZYo+//xzvf766+revbtGjBihESNGyOVy+dzHMAyNGDFCgwcPrtFaCYMBAAgBWVlZ6tKli1588UW/9k9LS1O/fv3Uq1cvbdiwQZMmTdLYsWO1aNGi6inQMKT8LP++cjOkT+6VZJT2QO5vSya49/Pn8YzSHudEpRp68skndcoppyg8PFxdunTRO++8I8k9wsFkMumjjz5Sly5dFBYWprPOOks//fSTz2MsWrRInTp1ksPhUHJysp555hmf2/Py8nTvvfeqWbNmcjgcatOmjebNm+ezz/fff69u3bopIiJCPXr00G+//Vah1+Hhcrn0yCOPqGnTpt6ugiVLlnhvz8/P12233abExESFhYUpOTlZU6dO9d7+0EMPqXnz5nI4HEpKStLYsWMrVQcAAABQHRwOhxo3bqymTZvq4osv1uDBg/Xpp596b58/f746dOigsLAwtW/fXjNnzvS5//bt23XNNdcoLi5O9erVU7du3fTtt99Kkv78809ddtllatSokSIjI3XmmWeW2clblo8//ljjx4/X0qVL9frrr+vyyy9Xly5ddNZZZ+nuu+/Wpk2btHPnTk2aNMnnfs8//7zGjBmjU045pZJHpnKYGQwAQAjo27ev+vbt6/f+s2fPVvPmzTV9+nRJUocOHbRu3To9/fTTuvLKK0u9T15envLy8rzXMzIy/C+wIFt6PMn//U/IcHcM/7uZf7tP2inZ6/n96Pfff7/effddzZo1S23atNGKFSv0z3/+Uw0aNPDuc8899+i5555T48aNNWnSJA0aNEibN2+WzWbT999/r6uvvloPPfSQBg8erNWrV2v06NGKj4/XsGHDJElDhgzRmjVr9Pzzz6tLly5KS0vT/v37feqYPHmynnnmGTVo0ECjRo3SiBEj9PXXX/v9Ojyee+45PfPMM5ozZ45OP/10vfzyyxo0aJB++eUXtWnTRs8//7wWL16st956S82bN9e2bdu0bds2SdI777yjZ599Vm+88YY6deqk3bt364cffqhwDQAAAEBN+Ouvv7RkyRLZbDZJ0ksvvaQpU6boxRdf1Omnn64NGzbopptuUr169TR06FBlZmbqvPPOU5MmTbR48WI1btxY69ev93bpZmZmql+/fnrssccUFhamhQsXauDAgfrtt9/UvHnzcuspKCjQ6NGjtWDBAv3tb3/TmjVrNG7cOP3111+68MILlZiYqPj4eL322mvq1KmTRo8e7dfjVqeAhsErVqzQU089pe+//167du3ya/jy8uXLNX78eP3yyy9KSkrSvffeq1GjRtVMwQAAhIg1a9bo4osv9tl2ySWXaN68eSooKPC+eTrW1KlT9fDDD9dUiQGRlZWladOm6YsvvtDZZ58tSTrllFO0atUqzZkzRzfffLMkacqUKbroooskSQsXLlTTpk313nvv6eqrr9a0adN0wQUX6IEHHpAktW3bVhs3btRTTz2lYcOGafPmzXrrrbe0bNkyXXjhhd7nON6//vUvnXfeeZKk++67T/3791dubq7CwsIq9JqefvppTZgwQddcc40k6YknntCXX36p6dOna8aMGdq6davatGmjc845RyaTSS1atPDed+vWrWrcuLEuvPBC2Ww2NW/eXN27d6/Q8wMAAADV6cMPP1RkZKQKCwuVm5srSZo2bZok6dFHH9UzzzyjK664QpLUsmVLbdy4UXPmzNHQoUP1v//9T/v27dPatWsVFxcnSWrdurX3sbt06aIuXbp4rz/22GN67733tHjxYt12223l1rZ8+XIlJCTo0ksv1ZEjRzRo0CDddNNNmjNnjr744gvde++9mjx5suLj43XRRRfp448/DniOGdAw2POR1+HDh5fZpXQs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yOtefPHFRpedeOKJfPPNNx28KhEREREREREREZHOxbbOYBERERERERERERGJHIXBIiIiIiIiIiIiIl2AwmAREZEY8eSTTzJgwAASEhIYM2YMS5Ysafb4RYsWMWbMGBISEhg4cCBPP/10hFYqIiIiIiIi0UhhsIiISAyYO3cuM2bM4M4772TFihVMnDiRs846q95Gq3Vt3ryZyZMnM3HiRFasWMEdd9zBb37zG958880Ir1xERERERESihcJgERGRGPDwww9z7bXXct111zF06FBmz55N3759eeqpp0Ie//TTT9OvXz9mz57N0KFDue6665g2bRoPPvhghFcuIiIiIiIi0UJhsIiISJSrrq5m+fLlTJo0qd7lkyZNYunSpSFvs2zZskbHn3HGGXz99dfU1NSEvE1VVRXFxcX13kRERERERKTzUBgsIiIS5QoKCvD5fOTk5NS7PCcnh/z8/JC3yc/PD3m81+uloKAg5G3uv/9+0tPTg299+/Ztny9AREREREREooLCYBERkRjhcDjq/d0wjEaXtXR8qMstt99+O0VFRcG37du3H+SKRUREREREJJq47V6AiIiINC8rKwuXy9VoCnjPnj2Npn8tPXv2DHm82+0mMzMz5G08Hg8ej6d9Fi0iIiIiIiJRR5PBIiIiUS4+Pp4xY8awYMGCepcvWLCACRMmhLzN+PHjGx0/f/58xo4dS1xcXIetVURERERERKKXwmAREZEYMGvWLJ577jnmzJnDunXrmDlzJtu2bWP69OmAWfEwderU4PHTp09n69atzJo1i3Xr1jFnzhyef/55br75Zru+BBEREREREbGZaiJERERiwKWXXsq+ffu49957ycvLY/jw4cybN4/+/fsDkJeXx7Zt24LHDxgwgHnz5jFz5kyeeOIJevXqxWOPPcZFF11k15cgIiIiIiIiNtNksIiISIy4/vrr2bJlC1VVVSxfvpwTTjgheN2LL77IwoUL6x1/4okn8s0331BVVcXmzZuDU8QiIiKd2ZNPPsmAAQNISEhgzJgxLFmypNnjFy1axJgxY0hISGDgwIE8/fTTEVqpiIhI5CkMFhERERERkU5h7ty5zJgxgzvvvJMVK1YwceJEzjrrrHqvnqlr8+bNTJ48mYkTJ7JixQruuOMOfvOb3/Dmm29GeOUiIiKRoTBYREREREREOoWHH36Ya6+9luuuu46hQ4cye/Zs+vbty1NPPRXy+Keffpp+/foxe/Zshg4dynXXXce0adN48MEHI7xyERGRyOhyncGGYQBQXFxs80pERKQrs34OWT+XopF+ZoqIiN1a8/Oyurqa5cuXc9ttt9W7fNKkSSxdujTkbZYtW8akSZPqXXbGGWfw/PPPU1NTQ1xcXKPbVFVVUVVVFfx7UVFRvbUerIrqsnb5OF2Rvyze7iXEJP1frz49BttGj7+2a6/HYLg/M7tcGFxSUgJA3759bV6JiIiI+XMpPT3d7mWEpJ+ZIiISLcL5eVlQUIDP5yMnJ6fe5Tk5OeTn54e8TX5+fsjjvV4vBQUF5ObmNrrN/fffzz333NPocv28jAIv2L2A2BSd/xOVmKPHX5u192OwpZ+ZXS4M7tWrF9u3byc1NRWHw3FQH6u4uJi+ffuyfft20tLS2mmFnZ/OW9vovLWNzlvb6Ly1XmvPmWEYlJSU0KtXrwisrm3a82dmrNB9v/3pnLY/ndP2pfPZ/trznLbl52XDn1mGYTT7cyzU8aEut9x+++3MmjUr+He/38/+/fvJzMzsMj8vo5EeyyL20eMvOoT7M7PLhcFOp5M+ffq068dMS0vTnb0NdN7aRuetbXTe2kbnrfVac86idSLY0hE/M2OF7vvtT+e0/emcti+dz/bXXuc03J+XWVlZuFyuRlPAe/bsaTT9a+nZs2fI491uN5mZmSFv4/F48Hg89S7LyMgIa43S8fRYFrGPHn/2C+dnpjaQExERERERkZgXHx/PmDFjWLBgQb3LFyxYwIQJE0LeZvz48Y2Onz9/PmPHjg3ZFywiIhLrFAaLiIiIiIhIpzBr1iyee+455syZw7p165g5cybbtm1j+vTpgFnxMHXq1ODx06dPZ+vWrcyaNYt169YxZ84cnn/+eW6++Wa7vgQREZEO1eVqItqTx+PhrrvuavQSIWmezlvb6Ly1jc5b2+i8tZ7OWeegf8f2p3Pa/nRO25fOZ/uz85xeeuml7Nu3j3vvvZe8vDyGDx/OvHnz6N+/PwB5eXls27YtePyAAQOYN28eM2fO5IknnqBXr1489thjXHTRRRFfuxwcPZZF7KPHX2xxGFY7voiIiIiIiIiIiIh0WqqJEBEREREREREREekCFAaLiIiIiIiIiIiIdAEKg0VERERERERERES6AIXBIiIiIiIiIiIiIl2AwuCD8OSTTzJgwAASEhIYM2YMS5YssXtJUWXx4sWce+659OrVC4fDwTvvvFPvesMwuPvuu+nVqxeJiYmcdNJJrFmzxp7FRon777+fo48+mtTUVLKzs7ngggtYv359vWN03hp76qmnGDlyJGlpaaSlpTF+/Hj+85//BK/XOWvZ/fffj8PhYMaMGcHLdN5Cu/vuu3E4HPXeevbsGbxe5y02hfP9V9ou1PcYab2dO3fys5/9jMzMTJKSkjjyyCNZvny53cuKWV6vl9/97ncMGDCAxMREBg4cyL333ovf77d7aTFD/98XERGJPQqD22ju3LnMmDGDO++8kxUrVjBx4kTOOusstm3bZvfSokZZWRmjRo3i8ccfD3n9X/7yFx5++GEef/xxvvrqK3r27Mnpp59OSUlJhFcaPRYtWsQNN9zA559/zoIFC/B6vUyaNImysrLgMTpvjfXp04cHHniAr7/+mq+//ppTTjmF888/P/jLhs5Z87766iueffZZRo4cWe9ynbemHXHEEeTl5QXfVq1aFbxO5y02hfP9V9qmqe8x0joHDhzguOOOIy4ujv/85z+sXbuWhx56iIyMDLuXFrP+/Oc/8/TTT/P444+zbt06/vKXv/DXv/6V//u//7N7aTFD/98XERGJQYa0yTHHHGNMnz693mVDhgwxbrvtNptWFN0A4+233w7+3e/3Gz179jQeeOCB4GWVlZVGenq68fTTT9uwwui0Z88eAzAWLVpkGIbOW2t069bNeO6553TOWlBSUmIMHjzYWLBggXHiiScaN910k2EYuq8156677jJGjRoV8jqdt86j4fdfaZumvsdI6916663G8ccfb/cyOpWzzz7bmDZtWr3LLrzwQuNnP/uZTSuKbfr/voiItJXf7zf8fr/dy+gyNBncBtXV1SxfvpxJkybVu3zSpEksXbrUplXFls2bN5Ofn1/vHHo8Hk488USdwzqKiooA6N69O6DzFg6fz8drr71GWVkZ48eP1zlrwQ033MDZZ5/NaaedVu9ynbfmbdy4kV69ejFgwAAuu+wyfvzxR0DnrTNp+P1X2qap7zHSeu+++y5jx47lkksuITs7m6OOOoq//e1vdi8rph1//PF89NFHbNiwAYBvv/2WTz/9lMmTJ9u8ss5BPxMlVvl8vpCXG4YR4ZWIdA1+vz9Yv7dq1SrWrl3Lnj17gtdJ+3PbvYBYVFBQgM/nIycnp97lOTk55Ofn27Sq2GKdp1DncOvWrXYsKeoYhsGsWbM4/vjjGT58OKDz1pxVq1Yxfvx4KisrSUlJ4e2332bYsGHBXzZ0zhp77bXX+Oabb/jqq68aXaf7WtPGjRvHSy+9xGGHHcbu3bv54x//yIQJE1izZo3OWycR6vuvtF5z32Ok9X788UeeeuopZs2axR133MGXX37Jb37zGzweD1OnTrV7eTHp1ltvpaioiCFDhuByufD5fPzpT3/i8ssvt3tpnYJ+JkosMgwDl8sFwL///W9cLhf9+vXjiCOOwOFw2Lw6kc7J6XSydetWfvGLX/D999+TlpZGYWEhixYtYuDAgXYvr1NSGHwQGv4wMAxDPyBaSeewaTfeeCPfffcdn376aaPrdN4aO/zww1m5ciWFhYW8+eabXHXVVSxatCh4vc5Zfdu3b+emm25i/vz5JCQkNHmczltjZ511VvD9ESNGMH78eA499FD+/ve/c+yxxwI6b7Guue+/Ep5wv8dI+Px+P2PHjuW+++4D4KijjmLNmjU89dRTCoPbaO7cufzjH//glVde4YgjjmDlypXMmDGDXr16cdVVV9m9vE5DPxMlljgcDlauXMlVV11FSUkJ2dnZrF+/nocffpgpU6aQnJxs9xJFOp05c+Zwzz33cOKJJ/LEE09QUFDAzJkzue2223j99dftXl6npJqINsjKysLlcjWaAt6zZ0+jZ74ltJ49ewLoHDbh17/+Ne+++y6ffPIJffr0CV6u89a0+Ph4Bg0axNixY7n//vsZNWoUjz76qM5ZE5YvX86ePXsYM2YMbrcbt9vNokWLeOyxx3C73cFzo/PWsuTkZEaMGMHGjRt1f+sEmvr+K63T0veYpl6CK03Lzc1l2LBh9S4bOnSoNi8+CLfccgu33XYbl112GSNGjODKK69k5syZ3H///XYvrVPQz0SJRX6/n7vvvptx48bx448/8vnnn3PTTTdxww03sHDhQruXJ9Ip5eXlccstt/DCCy8waNAgjj32WI499th6/xdXXUT7UhjcBvHx8YwZM4YFCxbUu3zBggVMmDDBplXFlgEDBtCzZ89657C6uppFixZ16XNoGAY33ngjb731Fh9//DEDBgyod73OW/gMw6CqqkrnrAmnnnoqq/+ZhT0AABnASURBVFatYuXKlcG3sWPHcsUVV7By5UoGDhyo8xamqqoq1q1bR25uru5vMayl77/SOi19j7FegivhO+6441i/fn29yzZs2ED//v1tWlHsKy8vx+ms/+uQy+XSL5ztRD8TJZo19aTkp59+yurVq3n88ccBuOuuu3j00Uc5//zzGT16dCSXKNLpWT9vf/WrX3HFFVcE/3+4ZMkS/vWvf+Hz+ZgzZw5Ao5/XcnBUE9FGs2bN4sorr2Ts2LGMHz+eZ599lm3btjF9+nS7lxY1SktL+eGHH4J/37x5MytXrqR79+7069ePGTNmcN999zF48GAGDx7MfffdR1JSEj/96U9tXLW9brjhBl555RX+9a9/kZqaGpykSE9PJzExEYfDofMWwh133MFZZ51F3759KSkp4bXXXmPhwoV88MEHOmdNSE1NbdSFmpycTGZmZvBynbfQbr75Zs4991z69evHnj17+OMf/0hxcTFXXXWV7m8xrKXvv9I64XyPkdaZOXMmEyZM4L777mPKlCl8+eWXPPvsszz77LN2Ly1mnXvuufzpT38K9oGuWLGChx9+mGnTptm9tJih/+9LLKrbC7x+/XrS09ODk+zW71wvv/wyf/jDH0hPT+fVV1/lzDPPBKCyslL1RyIHwev14nabUaQV8FobNnu9XmbPns2tt97K5ZdfTllZGbfccguLFi3ivvvuo3fv3ratu9MxpM2eeOIJo3///kZ8fLwxevRoY9GiRXYvKap88sknBtDo7aqrrjIMwzD8fr9x1113GT179jQ8Ho9xwgknGKtWrbJ30TYLdb4A44UXXggeo/PW2LRp04KPxR49ehinnnqqMX/+/OD1OmfhOfHEE42bbrop+Hedt9AuvfRSIzc314iLizN69eplXHjhhcaaNWuC1+u8xaZwvv/KwWn4PUZa77333jOGDx9ueDweY8iQIcazzz5r95JiWnFxsXHTTTcZ/fr1MxISEoyBAwcad955p1FVVWX30mKG/r8v0W737t3B971eb/D9DRs2GKNHjzb69+9vHHroocabb75peL1e49tvvzVGjhxpJCYmGs8880y97wevvvqqvu+KtJP//ve/9X6HsixZssTYuHFj8O+fffaZkZSUZHz99deRXF6n5zAMw4hk+CwiIiIiIiIi0pEeeeQRPvzwQ55++mn69u0LmPUwq1evZs6cOaSkpDBlyhRmz57NF198wSOPPMI555zDr3/9axYtWsTLL7/MqFGjAFi5ciW33HILI0eO5L777sPj8dj5pYnEDL/fj8PhCG4c+tlnn3HJJZeQkJDAvn37eOihh7j00ktJTU2tdzsjsNnopk2bOPzww3nnnXc455xz7PgSOiWFwSIiIiIiIiLSKezYsYM+ffrUqyyxXHXVVbzzzjuMHj2af/7zn2RlZQFwyimn0L17d5544gmKioq4/fbbmT9/PqeffjoJCQm8/fbbXHXVVcyePVs1ESJh8vv9wSqI0tJSUlJSuOuuu0hPT2fatGn87//+L4sXL2bGjBlcffXVIT/GPffcw1dffcXrr79OUlJSBFffuSkMFhEREREREZGYVlJSwsyZM9m7dy9vv/12MIT68ssvKS8v56STTmLLli2cdNJJ9O7dm/nz55OcnAzAvHnzmDFjBjfeeCO/+c1vAHj00UfZt28fBQUFTJ8+nZEjR9r2tYnEkoYh8PTp09m4cSNHHXUU+/fv55FHHgn2/5533nm4XC7uu+8+hg4dSk1NDStXrqSmpoZ77rmHtWvX8thjj/GTn/zEzi+p09F2fCIiIiIiIiIS01JTU+nXrx8FBQXMnTsXgLy8PK655hqef/559uzZwyGHHMI111zDnj17+PTTT4O3nTx5Msceeyzvv/8+S5YsAeCmm27i3nvv5cknn1QQLNIKVhC8evVq7rvvPgoKCjjvvPN4/fXXWbJkSb3p+unTp7N161befvttwHxS56WXXuLyyy8nNzeXdevWKQjuAAqDRURERERERCRm+f1+AKZNm0Zubi6vvvoq+fn55ObmMm3aNH744Qf+/e9/A3DHHXfg8Xh48803ycvLC36M2267jeXLl/Phhx/i9Xpt+TpEOoOKigpuv/12TjvtNFavXs3LL7/MnXfeyTPPPENubi5PPvlk8NjJkydzzDHH8Mknn/Dxxx/TvXt3brjhBhYvXsyLL75ISkoKPp/Pxq+mc1IYLCIiIiIiIiIxxwqBnU4nhmHQp08fzj//fPbu3csLL7wAwK9+9SsyMjL4z3/+w7p164iLi+O3v/0t//3vf1m0aFHwYw0bNoznnnuOm2++GbfbbcvXI9IZJCYmMmzYMLp164bD4SAzMxMwKyHGjx/Phx9+yPLly4PHX3/99fzwww8sW7YMn8/HkCFD6N+/P36/H7/fj8vlsutL6bQUBouIiIiIiIhITPH5fMGXoxcXF+NwOAC44IILGD58OPPnz+fbb78lKSmJa665hk2bNvHee+8BMHXqVIYMGcLf/vY31qxZE/yYF1xwAampqZH/YkQ6CWtbsnPPPZfTTjuNr7/+mh07dgDg8Xi49NJLcblcvPjii8HbjBw5kldeeYU777yzXvDrdDqDj3FpXzqrIiIiIiIiIhJTXC4X27dv59JLL+WCCy7g8ssv58MPPyQ1NZUrrrgCr9fLnDlzAJgyZQrDhw/no48+CnYF33bbbRQWFhIfH2/nlyHSqVhPymRkZHDhhRcyYMAA/vznPwevP+GEEzjxxBNZsGABb731VvDy8ePHA7XT/tKxFAaLiIiIiIiISEz5z3/+w7hx4/B4PFx11VXk5ORw2WWX8e6773LSSSdxwgkn8NVXXzFv3jwAbrjhBvbt28fLL79MeXk5J598MsuXL2fw4ME2fyUi0c8wjLCDWms6+LjjjmPy5MksWLCAZcuWBa+/+OKLueCCCxg9enSj22oSODJ0lkVEREREosjChQtxOBwUFhbavRQREdv5/f5guFTXBx98wMUXX8xLL73EVVddxaRJk9i/fz8rV64E4PLLLycjI4NXX32VyspKxo0bx3HHHUd2djYulyvkxxSRxnw+Hw6HA6fTyYEDBygpKWl2k0WHw4FhGMTHx3P22WczZMgQ/vjHPwavP+KII3jggQc45JBDIrB6CUVhsIg06eqrr+aCCy6wexkiIiIiItIFWb3ADoeDH374gbVr1wJQU1PDu+++yxVXXMHGjRsZNWoU06dP56mnnuL3v/89AMOHD+ess85i5cqVPPPMMwA8+OCD3HPPPXg8nuDL2UWkeVaP78yZMxk9ejRnn3025513Htu3b2/yNtbja9SoUZx88sls3ryZ1atX1ztGlRD2URgsIiIiIiIiIlHH5XJRUFDAxRdfzOmnn868efPYvXs3fr+fkSNHcskllzB27FhOO+00vvnmG375y19SU1PDwoULAbjwwgsZN24cw4YNAyAuLs7Gr0YkNpWWlnLRRRexbNkynnrqKR599FFKSkqYNm0ay5cvb/J21vT9z372M5YtW8bw4cPrXa9KCPvozIsIb7zxBiNGjCAxMZHMzExOO+00brnlFv7+97/zr3/9C4fDgcPhCP6naufOnVx66aV069aNzMxMzj//fLZs2RL8eNZE8T333EN2djZpaWn88pe/pLq62p4vUEREpBUMw+Avf/kLAwcOJDExkVGjRvHGG28AtRUO77//PqNGjSIhIYFx48axatWqeh/jzTff5IgjjsDj8XDIIYfw0EMP1bu+qqqK3/72t/Tt2xePx8PgwYN5/vnn6x2zfPlyxo4dS1JSEhMmTGD9+vUd+4WLiESZZcuWceyxx+L3+3n99de57LLLyMnJIS4ujhEjRuBwOHj00Ud56KGHyMzMBGDJkiU8+OCDbN68md69e/O3v/2N008/3eavRCQ2hJrW3bRpE1u2bGHu3LmceeaZZGRksGvXLgoLC3G73c1+PJ/PR2ZmJunp6a3qHZaOpTBYpIvLy8vj8ssvZ9q0aaxbt46FCxdy4YUXctdddzFlyhTOPPNM8vLyyMvLY8KECcHNFlJSUli8eDGffvopKSkpnHnmmfXC3o8++oh169bxySef8Oqrr/L2229zzz332PiVioiIhOd3v/sdL7zwAk899RRr1qxh5syZ/OxnP2PRokXBY2655RYefPBBvvrqK7KzsznvvPOoqakBzBB3ypQpXHbZZaxatYq7776b3//+97z44ovB20+dOpXXXnuNxx57jHXr1vH000+TkpJSbx133nknDz30EF9//TVut5tp06ZF5OsXEYm0hr3A1vsrV66kZ8+evPXWWxx99NH07NkTMCcKL7/8coYMGcIjjzzCRx99xHfffcdf//pXrr76agYNGkSPHj0AVAchEgarA9jpdFJcXMw777zDgQMHAFi6dCkej4f+/fszZcoUjjzySM4//3w++OADRo0a1eTHczgcuFwuCgsLWbNmTbB3WOznMNSaLtKlffPNN4wZM4YtW7bQv3//etddffXVFBYW8s477wQvmzNnDn/5y19Yt25d8D9W1dXVZGRk8M477zBp0iSuvvpq3nvvPbZv305SUhIATz/9NLfccgtFRUX6ASAiIlGrrKyMrKwsPv74Y8aPHx+8/LrrrqO8vJxf/OIXnHzyybz22mtceumlAOzfv58+ffrw4osvMmXKFK644gr27t3L/Pnzg7f/7W9/y/vvv8+aNWvYsGEDhx9+OAsWLOC0005rtIaFCxdy8skn8+GHH3LqqacCMG/ePM4++2wqKipISEjo4LMgIhI5Pp8v2ElaVlZGcnJy8LpZs2bx9ddfM336dDZt2sT+/fv59NNPGTFiBE888QR5eXn84he/YNOmTSQlJVFTU8Nf/vIX7Xsi0kbfffcdzzzzDO+++y5PP/00Z599NkuXLuWMM86gqqqK888/n9///veMHDkSgC+//BKv18uxxx6L0+ms93gGuOuuu7jvvvt48sknmTZtWr3rxD7Nz3OLSKc3atQoTj31VEaMGMEZZ5zBpEmTuPjii+nWrVvI45cvX84PP/xAampqvcsrKyvZtGlTvY9rBcEA48ePp7S0lO3btzcKnUVERKLF2rVrqaysbPSS4urqao466qjg3+sGxd27d+fwww9n3bp1AKxbt47zzz+/3u2PO+44Zs+ejc/nY+XKlbhcLk488cRm12L9ogWQm5sLwJ49e+jXr1/bvjgRkSjkcrkoLS3ltttuY/369RxxxBFMnjyZSZMmcckll1BYWMgvfvELzjzzTAYOHMjpp5/O22+/zU033cSzzz7LvHnzqKio4IcffmDMmDF2fzkiMWn+/PlcccUVjB07lvLycvbu3cvcuXM59thj6du3LyeddBI7duzgn//8Z/A2RUVF/N///R/Dhw9n3Lhx+P3+YNg7d+5cfvvb35KVlcXbb7/NOeecY9eXJiEoDBbp4lwuFwsWLGDp0qXMnz+f//u//+POO+/kiy++CHm83+9nzJgxvPzyy42us16K1Ry9TEtERKKZ1WX3/vvv07t373rXeTyeek98NmT9jDMMo9HPu7ovxktMTAxrLXU3OrI+nrr2RKSzefPNN7nxxhsZNWoUJ598MmvWrOGiiy7i+++/Z/z48YwaNYpHHnmElJSUYNC0du1aMjIyMAwDl8tFenq6gmCRMFj/j3A6ncH/r9TU1PCHP/yBSy65hCeffJKdO3fy+uuv8/vf/57Jkydz2WWXcdVVVzF9+nSmTp3KSSedRGJiIvfeey8ZGRncfPPNwcfmt99+y4033simTZu49dZb+dWvfkV8fLydX7KEoNdqiwgOh4PjjjuOe+65hxUrVhAfH8/bb79NfHw8Pp+v3rGjR49m48aNZGdnM2jQoHpv6enpweO+/fZbKioqgn///PPPSUlJoU+fPhH7ukRERFpr2LBheDwetm3b1ujnXN++fYPHff7558H3Dxw4wIYNGxgyZEjwY3z66af1Pu7SpUs57LDDcLlcjBgxAr/fX6+DWESks9q7dy9g1kE0/N1i9+7dLFu2jDvvvJMPPviAO+64gyuvvJKysjJuv/12qqurSUpKIj09nfLycioqKnj22WdZvXo1J598crCTVERC83q9PP7443z88ceAGQJbdQ7WE83r1q1j48aNnH322QD07t2bmTNnMnbsWJ555hm2bNnCxRdfzCuvvMLmzZv529/+xp/+9CeuuOIKli1bFuwNLi4u5oorrmDEiBGsXLmSm266SUFwlNJksEgX98UXX/DRRx8xadIksrOz+eKLL9i7dy9Dhw6lsrKS//73v6xfvz64A+gVV1zBX//6V84//3zuvfde+vTpw7Zt23jrrbe45ZZbgmFvdXU11157Lb/73e/YunUrd911FzfeeKP6gkVEJKqlpqZy8803M3PmTPx+P8cffzzFxcUsXbqUlJSUYNXRvffeS2ZmJjk5Odx5551kZWUFOyr/53/+h6OPPpo//OEPXHrppSxbtozHH3+cJ598EoBDDjmEq666imnTpvHYY48xatQotm7dyp49e5gyZYpdX7qISLv74x//yPLly3n44YcZMGAAADt37mTnzp2MHj2anJwcJk+ezLHHHsuOHTv41a9+xRdffMG1117LnDlzuPDCC7ngggv44osvePnll1m6dCm7du3i0Ucf5ayzzrL5qxOJfjU1NTz88MOcc845wSdQ/vjHP7Jw4UIOPfRQpk2bxmGHHUZJSUkwuLW6u++77z6OP/543n77bX75y18yadIkJk2axP79+0lOTsbj8QAEn+RJS0tj4cKFZGVl2fb1SniUyoh0cWlpaSxevJjJkydz2GGH8bvf/Y6HHnqIs846i5///OccfvjhjB07lh49evDZZ5+RlJTE4sWL6devHxdeeCFDhw5l2rRpVFRUkJaWFvy4p556KoMHD+aEE05gypQpnHvuudx99932faEiIiJh+sMf/sD//u//cv/99zN06FDOOOMM3nvvvWCQAfDAAw9w0003MWbMGPLy8nj33XeDv0SNHj2a119/nddee43hw4fzv//7v9x7771cffXVwds/9dRTXHzxxVx//fUMGTKEn//855SVlUX6SxUR6VBnnXUW27Zt44MPPgBg5syZDBo0iEsuuYTTTz+d119/nVNOOQWHw8Evf/lLkpKS+Pzzz/nb3/7GMcccw+zZsykpKeGoo45i4MCB/PKXv2TXrl1ccsklNn9lIrEhMTGR2bNn8+WXX/LKK69w22238Y9//IOJEyfy+eefM3XqVF588UWuu+467rjjDoDgJo7JyckkJiby7rvv8t133wU/Zrdu3fB4PPh8vmBVizWhryA4NjiMugVmIiLt4Oqrr6awsJB33nnH7qWIiIi0q4ULF3LyySdz4MABMjIy7F6OiEjUu+GGG9i7dy9jxozhs88+44477qCkpITXXnuNN998kw8//BC/3895553HvHnzGD16NLt27eKMM85gzZo13Hvvvfzud7/D7/frVYYibeD3+znnnHNITU2lsLCQhx9+mCOOOIKCggKeeOIJHnjgAebMmcOMGTP47W9/yy9+8QtSU1N59tlnWbVqFf/85z+55ZZb+J//+R+7vxRpJ6qJEBEREREREZEOcddddzF58mSWL1/ODTfcwLHHHgvAyJEj2b9/P7NmzeLFF19kz549lJeXU1VVxfvvv88555zDrbfeyhFHHAGgIFikjZxOJ3/+85859dRTyc7ODj6msrKymDZtGu+//z7z58/niSee4Oqrr+aVV14hJSWF5cuXs3btWsrLy3njjTcUBnci+m4qIiIiIiIiIh0iOzubn//852zZsoXExMTg5T169ODGG29kzZo1fP/99/zsZz/j3HPP5bDDDuOOO+5g/Pjx/OxnP+Ooo46ycfUincOIESO4/PLLqays5Isvvghe3rdvXyZNmsSOHTu4+OKLeffdd7n00ks55phj2LhxI/369aOgoIC+ffvi9/tRuUDnoMlgEWl3L774ot1LEBER6RAnnXSSfhESEWmla665hjlz5vDZZ59x0UUXkZ2djdPppGfPnnTv3h2Hw8Hf/vY3PvroI3bv3s0111xj95JFOp3f//73LF68mLfffptx48YFL//xxx9xOBwAnHLKKZxyyinB61544QW+/fZbHnroIU3ndyIKg0VERERERESkw8THx/OHP/yBW2+9lVdeeYUZM2YAUFlZSUlJCZmZmXg8HiZPnmzvQkU6saysLK699loeeOABEhMTueSSS9i/fz/Lly9n6tSpweP27t3LBx98wCOPPMKOHTt48MEHueiii2xcubQ3bSAnIiIiIiIiIh3KMAwuvvhi5s+fz+WXX86wYcN48MEHOfLII3nppZfo3r273UsU6fSqq6s54YQTWL16NSeffDI//vgjJ510Ek888US94z7//HPWrFnDtddea9NKpSMpDBYRERERERGRDrd582bGjx/P4YcfzujRoxk0aBA33HCD3csS6VI++OADbrnlFv70pz9x/PHHB5+I8fv9qoLoIhQGi4iIiIiIiEhE3HTTTYwfP54pU6YoeBKxgWEYrFu3jmHDhgFmCAzo8diFKAwWERERERERkYjQ9KFI9DAMI7h5nHQdCoNFREREREREREREugA9HSciIiIiIiIiIiLSBSgMFhEREREREREREekCFAaLiIiIiIiIiIiIdAEKg0VERERERERERES6AIXBIiIiIiIiIiIiIl2AwmARERERERERERGRLkBhsIiIiIiIiIiIiEgXoDBYREREREREREREpAtQGCwiIiIi8v/bsQMBAAAAAEH+1oNcGAEAwIAMBgAAAAAYCL4/XVzo9y6oAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1400x600 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最后 epoch_loss: [0.07709380217711441, 0.08098416924476623, 0.1126649484038353, 0.06944410153664649, 0.026943660387769342]\n",
      "最后 epoch_acc: [0.9675000190734864, 0.9754762053489685, 0.9779762029647827, 0.9725000143051148, 0.9900000095367432]\n",
      "最后 5 个 step loss: [0.032571591436862946, 0.026578854769468307, 0.025565046817064285, 0.049150269478559494, 0.000852539436891675]\n"
     ]
    }
   ],
   "source": [
    "# 可视化训练历史（training_history.json）\n",
    "# 从 output_dir 读取 training_history.json 并绘制 step loss / epoch loss / epoch acc，并显示 config 表格\n",
    "import os\n",
    "import json\n",
    "from pathlib import Path\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "out_dir = config.get('output_dir') if isinstance(config, dict) else './models/bge-m3-finetuned'\n",
    "hist_path = os.path.join(out_dir, 'training_history.json')\n",
    "\n",
    "if not os.path.exists(hist_path):\n",
    "    print(f\"未找到训练历史文件: {hist_path}\\n请先运行训练并确保 training_history.json 已写入 output_dir。\")\n",
    "else:\n",
    "    with open(hist_path, 'r', encoding='utf-8') as hf:\n",
    "        hist = json.load(hf)\n",
    "\n",
    "    step_losses = hist.get('step_losses', [])\n",
    "    step_accs = hist.get('step_accs', [])\n",
    "    epoch_idx = hist.get('epoch', [])\n",
    "    epoch_loss = hist.get('epoch_loss', [])\n",
    "    epoch_acc = hist.get('epoch_acc', [])\n",
    "\n",
    "    print('Loaded history from', hist_path)\n",
    "    print(f\"steps: {len(step_losses)}, epochs: {len(epoch_idx)}\")\n",
    "\n",
    "    # 尝试读取评估结果（eval_results.json），格式为 {model_name: {\"recall@1\":..., \"mrr\":..., \"n\":...}, ...}\n",
    "    eval_path = os.path.join(out_dir, 'eval_results.json')\n",
    "    eval_results = None\n",
    "    if os.path.exists(eval_path):\n",
    "        try:\n",
    "            with open(eval_path, 'r', encoding='utf-8') as ef:\n",
    "                eval_results = json.load(ef)\n",
    "            print('Loaded eval results from', eval_path)\n",
    "        except Exception as e:\n",
    "            print('读取 eval_results.json 失败:', e)\n",
    "\n",
    "    # 显示 config 的重要参数表格（使用 matplotlib table，避免额外依赖）\n",
    "    try:\n",
    "        cfg = config if isinstance(config, dict) else {}\n",
    "        keys = [\n",
    "            'train_file', 'model_path', 'output_dir', 'epochs', 'batch_size', 'lr',\n",
    "            'accumulation_steps', 'fp16', 'temperature', 'query_max_len', 'passage_max_len',\n",
    "            'weight_decay', 'num_workers'\n",
    "        ]\n",
    "        rows = []\n",
    "        for k in keys:\n",
    "            v = cfg.get(k, None)\n",
    "            if v is None:\n",
    "                # 尝试从 globals 中获取替代值\n",
    "                v = globals().get(k, '')\n",
    "            rows.append([str(v)])\n",
    "\n",
    "        fig_table = plt.figure(figsize=(8, max(0.6, 0.18 * len(rows))))\n",
    "        ax_table = fig_table.add_subplot(111)\n",
    "        ax_table.axis('off')\n",
    "        table = ax_table.table(cellText=rows, rowLabels=keys, colLabels=['value'], loc='center', cellLoc='left')\n",
    "        table.auto_set_font_size(False)\n",
    "        table.set_fontsize(9)\n",
    "        table.scale(1, 1.2)\n",
    "        plt.title('Config summary', fontsize=10)\n",
    "        plt.show()\n",
    "    except Exception as e:\n",
    "        print('绘制 config 表格失败:', e)\n",
    "\n",
    "    # 绘图：1 行 3 列（左: step losses, 中: epoch metrics, 右: eval metrics）\n",
    "    fig = plt.figure(constrained_layout=True, figsize=(14,6))\n",
    "    gs = fig.add_gridspec(1, 3)\n",
    "\n",
    "    ax0 = fig.add_subplot(gs[0, 0])\n",
    "    if step_losses:\n",
    "        ax0.plot(step_losses, color='tab:blue', alpha=0.8)\n",
    "        ax0.set_title('Step losses')\n",
    "        ax0.set_xlabel('step')\n",
    "        ax0.set_ylabel('loss')\n",
    "    else:\n",
    "        ax0.text(0.5, 0.5, 'no step_losses', ha='center', va='center')\n",
    "        ax0.set_title('Step losses')\n",
    "        ax0.set_xticks([])\n",
    "        ax0.set_yticks([])\n",
    "\n",
    "    ax1 = fig.add_subplot(gs[0, 1])\n",
    "    if epoch_loss:\n",
    "        ax1.plot(epoch_idx, epoch_loss, marker='o', label='epoch_loss', color='tab:orange')\n",
    "    if epoch_acc:\n",
    "        ax1.plot(epoch_idx, epoch_acc, marker='x', label='epoch_acc', color='tab:green')\n",
    "    ax1.set_title('Epoch metrics')\n",
    "    ax1.set_xlabel('epoch')\n",
    "    ax1.legend()\n",
    "\n",
    "    ax2 = fig.add_subplot(gs[0, 2])\n",
    "    if eval_results:\n",
    "        # 将 eval_results 按模型名排序并绘制 grouped bar（Recall@1 和 MRR）\n",
    "        model_names = list(eval_results.keys())\n",
    "        recall_vals = [eval_results[m].get('recall@1', 0.0) for m in model_names]\n",
    "        mrr_vals = [eval_results[m].get('mrr', 0.0) for m in model_names]\n",
    "        x = np.arange(len(model_names))\n",
    "        width = 0.35\n",
    "        ax2.bar(x - width/2, recall_vals, width, label='Recall@1', color='tab:purple')\n",
    "        ax2.bar(x + width/2, mrr_vals, width, label='MRR', color='tab:cyan')\n",
    "        ax2.set_xticks(x)\n",
    "        ax2.set_xticklabels(model_names, rotation=30)\n",
    "        ax2.set_ylim(0, 1.0)\n",
    "        ax2.set_title('Evaluation comparison')\n",
    "        ax2.legend()\n",
    "        for i, v in enumerate(recall_vals):\n",
    "            ax2.text(i - width/2, v + 0.02, f\"{v:.3f}\", ha='center', va='bottom', fontsize=8)\n",
    "        for i, v in enumerate(mrr_vals):\n",
    "            ax2.text(i + width/2, v + 0.02, f\"{v:.3f}\", ha='center', va='bottom', fontsize=8)\n",
    "    else:\n",
    "        ax2.text(0.5, 0.5, 'no eval_results.json', ha='center', va='center')\n",
    "        ax2.set_title('Evaluation comparison')\n",
    "        ax2.set_xticks([])\n",
    "        ax2.set_yticks([])\n",
    "\n",
    "    plt.show()\n",
    "\n",
    "    # 额外打印最后几个值便于快速判断\n",
    "    if epoch_loss:\n",
    "        print('最后 epoch_loss:', epoch_loss[-5:])\n",
    "    if epoch_acc:\n",
    "        print('最后 epoch_acc:', epoch_acc[-5:])\n",
    "    if step_losses:\n",
    "        print('最后 5 个 step loss:', step_losses[-5:])\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "train_code_embedding",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
